টুকরোগুলি সহ অ্যাকশনবারে নেভিগেশন আপ


88

আমার কাছে একটি ট্যাবড অ্যাকশনবার / ভিউপেজ লেআউট আছে যা তিনটি ট্যাব , বি এবং সি বলে । ট্যাবে সি ট্যাব (টুকরা), আমি অন্য টুকরা বলে টুকরা যোগ করছি ডি । সঙ্গে

 DFragment f= new DFragment();
 ft.add(android.R.id.content, f, "");
 ft.remove(CFragment.this);
 ft.addToBackStack(null);
 ft.commit();

আমি ডিফ্রেগমেন্টের অন রেসুমে অ্যাকশনবারটি সংশোধন করেছি বোতামটি যোগ করতে:

ActionBar ab = getActivity().getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
ab.setDisplayHomeAsUpEnabled(true);
ab.setDisplayShowHomeEnabled(true);

এখন ডিফ্রেগমেন্টে, যখন আমি হার্ডওয়্যার (ফোন) ব্যাক বোতাম টিপুন, আমি সিফ্রেগমেন্ট সিলেক্ট করে আসল ট্যাবড (এবিসি) লেআউটে ফিরে আসি। অ্যাকশনবার আপ বোতামের সাহায্যে আমি কীভাবে এই কার্যকারিতাটি অর্জন করতে পারি?


উত্তর:


186

OnBackStackChangedListenerআপনার ফ্রেগমেন্ট ক্রিয়াকলাপটিতে এই কোডটি প্রয়োগ করুন এবং যুক্ত করুন।

@Override
public void onCreate(Bundle savedInstanceState) {
    //Listen for changes in the back stack
    getSupportFragmentManager().addOnBackStackChangedListener(this);
    //Handle when activity is recreated like on orientation Change
    shouldDisplayHomeUp();
}

@Override
public void onBackStackChanged() {
    shouldDisplayHomeUp();
}

public void shouldDisplayHomeUp(){
   //Enable Up button only  if there are entries in the back stack
   boolean canGoBack = getSupportFragmentManager().getBackStackEntryCount()>0;
   getSupportActionBar().setDisplayHomeAsUpEnabled(canGoBack);
}

@Override
public boolean onSupportNavigateUp() {
    //This method is called when the up button is pressed. Just the pop back stack.
    getSupportFragmentManager().popBackStack();
    return true;
}

21
সম্পর্কে onSupportNavigateUp(), "পদ্ধতিটি তার সুপারক্লাস থেকে পদ্ধতিটি ওভাররাইড করে না"।
ফ্রেড

10
আপনার যদি ইতিমধ্যে একটি থাকে onOptionsItemSelectedতবে android.R.id.homeযোগ করার পরিবর্তে আইটেম আইডের জন্য পরীক্ষা করাও সম্ভব onSupportNavigateUp
ডোমসোম

4
যদি এপিআই সংস্করণ> = 14, তবে ওপরে সমর্থন ন্যাভিগেটআউপ @ ওভাররাইড পাবলিক বুলিয়ান অনভিগেটআপ () ver // এর পরিবর্তে অন্যাভিগেটআপ ব্যবহার করুন // আপ বোতামটি টিপলে এই পদ্ধতিটি বলা হয়। ঠিক পপ ব্যাক স্ট্যাক। getFragmentManager ()। পপব্যাকস্ট্যাক (); সত্য প্রত্যাবর্তন; }
তেজস্বী হেগদে

4
আপনার অ্যাপ্লিকেশন আইকনের পাশে প্রদর্শিত একটি আপ ক্যারেট থাকার কথা আছে ActionBar? আমি এই কোডটি প্রয়োগ করার সময় একটিও দেখতে পাচ্ছি না। আমি কেবল আইকনে ক্লিক করতে সক্ষম, তবে এটি কিছুই করে না। Android 4.0+।
আজুরস্পট

4
যদি অনব্যাকস্ট্যাক চ্যাঞ্জড () ওভাররাইড না করে তবে নিশ্চিত হয়ে নিন যে আপনার ক্রিয়াকলাপটি ফ্র্যাগমেন্টম্যানেজার.অনব্যাকস্ট্যাক চ্যাঞ্জডলিস্টনার ইন্টারফেস প্রয়োগ করে।
সিবিএ 1110

42

আমি বুঝতে পেরেছি. শুধু ওভাররাইড onOptionsItemSelected কার্যকলাপ হোস্টিং এবং backstack যেমন পপআপ

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home: {
            FragmentManager fm = getSupportFragmentManager();
            if (fm.getBackStackEntryCount() > 0) {
                fm.popBackStack();
                return true;
            }
            break;
        }
    }
    return super.onOptionsItemSelected(item);
}

নীচে একটি উত্তরে বর্ণিত হিসাবে কল করুন getActionBar().setDisplayHomeAsUpEnabled(boolean);এবং getActionBar().setHomeButtonEnabled(boolean);ইন করুন onBackStackChanged()


4
আপনাকে getActivity ()। getActionBar () সেটডিসপ্লেহোমএএসআপ্পেনড (মিথ্যা) কল করতে হবে; একবার আপনি যখন পিছনের স্ট্যাকটি পপ করবেন তখন আপ বোতামটি সরাতে
জেপ করুন

এটি করার সঠিক উপায় এটি নয়। এটি আপ বোতামটি সক্রিয় রাখে।
রজার গারজন নিতো

4
আপনার সেই কোডটি switchস্টেটমেন্টের সাথে কেস সহ করা উচিত android.R.id.home
ফ্রেড

18

যদি আপনার একটি পিতামাতার ক্রিয়াকলাপ থাকে এবং ব্যাক বোতাম হিসাবে কাজ করতে এই আপ বোতামটি চান, আপনি এই কোডটি ব্যবহার করতে পারেন:

আপনার মূল ক্রিয়াকলাপ শ্রেণিতে এটি onCreate এ যুক্ত করুন

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
            if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment)
                getSupportActionBar().setHomeButtonEnabled(true);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            } else {
                getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                getSupportActionBar().setHomeButtonEnabled(false);
            }
        }

    });

এবং তারপরে ওপশনস আইটেমসলেক্ট করা যুক্ত করুন:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            getSupportFragmentManager().popBackStack();
            return true;
     ....
 }

আমি সাধারণত সব সময় এটি ব্যবহার করি এবং বেশ আইনী মনে হয়


4
আমি এই কোডটি হুবহু চেষ্টা করেছি, Activityআমার একটিতে, আশা করে যে এটি যে খণ্ডটি থেকে শুরু হয়েছিল তা ফিরে আসবে। আমি যখন আমার কাছে যাই তখন পিছনের বোতামটি আমার অ্যাপ্লিকেশন আইকনের কাছে উপস্থিত হয় Activityতবে আমি আইকনটিতে ক্লিক করি এবং কিছুই ঘটে না (এটি খণ্ডে ফিরে যেতে হবে)। কোন ধারণা কেন? ধন্যবাদ
আজুরস্পট

4
@ ড্যানিয়েল আপনার কোডটি বৈধ .. এটি কার্যকর করে। আপনি কেবল ক্যাচ অপশনের মাধ্যমে এটিকে ঘিরে ফেলতে চাইতে পারেন .. যে কোনও অপ্রত্যাশিত ব্যতিক্রম এবং অ্যাপ্লিকেশন ক্র্যাশ হওয়া রোধ করতে জানেন
Zuko

4
@ ননিএ এটি কেবল পূর্ববর্তী টুকরাটিতে ফিরে যেতে চলেছে (যেমন, খণ্ড খ -> টুকরা এ), আপনি যদি নতুন ক্রিয়াকলাপে 1 টি টুকরা স্ফীত করছেন তবে এটি পূর্বের ক্রিয়াকলাপে ফিরে যাবে না।
ড্যানিয়েল জোনকার

11

আপনি পিছনের বোতামের মতো আপ বোতামটি দিয়ে ফিরে যেতে পারেন;

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            super.onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

8

আমি জানি এই প্রশ্নটি পুরানো, তবে এমন কেউ হতে পারে (আমার মতো) এরও এটির প্রয়োজন।

যদি আপনার ক্রিয়াকলাপ অ্যাপকম্প্যাটঅ্যাক্টিভিটি প্রসারিত করে তবে আপনি একটি সহজ (দ্বি-পদক্ষেপ) সমাধান ব্যবহার করতে পারেন:

1 - আপনি যখনই কোনও হোম-হোম খণ্ড যুক্ত করবেন তখনই খণ্ডের লেনদেনের পরে ডানদিকে আপ আপ বোতামটি দেখান। এটার মত:

    // ... add a fragment
    // Commit the transaction
    transaction.commit();

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

2 - তারপরে ইউপি বোতাম টিপলে আপনি এটি লুকিয়ে রাখুন।

@Override
public boolean onSupportNavigateUp() {
    getSupportActionBar().setDisplayHomeAsUpEnabled(false);        
    return true;
}

এটাই.


7

আমি রজার গারজন নিতো এবং সোহেলজিজের উত্তরগুলির সংমিশ্রণটি ব্যবহার করেছি । আমার অ্যাপ্লিকেশনটিতে একটি একক মেইনঅ্যাক্টিভিটি রয়েছে এবং এতে এ, বি, সি টুকরা রয়েছে। আমার "হোম" খণ্ডটি (এ) অনব্যাকস্ট্যাক চ্যাঞ্জডলিস্টনার প্রয়োগ করে এবং ব্যাকস্ট্যাকের আকার পরীক্ষা করে; যদি এটি একেরও কম হয়, তবে এটি ইউপি বোতামটি আড়াল করে। খণ্ড বি এবং সি সর্বদা পিছনের বোতামটি লোড করে (আমার ডিজাইনে, বি এ থেকে আরম্ভ করা হয়, এবং সি থেকে বি চালু করা হয়)। মেইনএ্যাকটিভিটি নিজেই কেবল ইউপি বোতামের ট্যাপের ব্যাকস্ট্যাকটি পপ করে, এবং বোতামটি দেখানোর / আড়াল করার জন্য বিভিন্ন পদ্ধতি রয়েছে যা টুকরো টুকরো বলে:

প্রধান কাজ:

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            getSupportFragmentManager().popBackStack();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

public void showUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(true); }
public void hideUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(false); }

ফ্র্যাগমেন্টএ (ফ্র্যাগমেন্ট ম্যানেজ.অনব্যাকস্ট্যাক চ্যাঞ্জডলিস্টনার প্রয়োগ করে):

public void onCreate(Bundle savedinstanceSate) {
    // listen to backstack changes
    getActivity().getSupportFragmentManager().addOnBackStackChangedListener(this);

    // other fragment init stuff
    ...
}

public void onBackStackChanged() {
    // enable Up button only  if there are entries on the backstack
    if(getActivity().getSupportFragmentManager().getBackStackEntryCount() < 1) {
        ((MainActivity)getActivity()).hideUpButton();
    }
}

খণ্ড বি, খণ্ড

public void onCreate(Bundle savedinstanceSate) {
    // show the UP button
    ((MainActivity)getActivity()).showUpButton();

    // other fragment init stuff
    ...
}

5

এটি আমার পক্ষে কাজ করেছে। ওপেনরাইড সাপোর্টনাভিগেটআপ এবং অনব্যাকপ্রেসড, উদাহরণস্বরূপ (কোটলিনে কোড);

override fun onBackPressed() {
    val count = supportFragmentManager.backStackEntryCount
    if (count == 0) {
        super.onBackPressed()
    } else {
        supportFragmentManager.popBackStack()
    }
}

override fun onSupportNavigateUp(): Boolean {
    super.onSupportNavigateUp()
    onBackPressed()
    return true
}

এখন খণ্ডে, যদি আপনি উপরের তীরটি প্রদর্শন করেন

activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)

এটিতে ক্লিক করা আপনাকে আগের ক্রিয়াকলাপটি ফিরিয়ে আনবে।


5

কোটলিন:

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        supportFragmentManager.addOnBackStackChangedListener { setupHomeAsUp() }
        setupHomeAsUp()
    }

    private fun setupHomeAsUp() {
        val shouldShow = 0 < supportFragmentManager.backStackEntryCount
        supportActionBar?.setDisplayHomeAsUpEnabled(shouldShow)
    }

    override fun onSupportNavigateUp(): Boolean = 
        supportFragmentManager.popBackStack().run { true }

    ...
}

2

এটি একটি খুব ভাল এবং নির্ভরযোগ্য সমাধান: http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-frations/

লোকটি একটি বিমূর্ত অংশ তৈরি করেছে যা ব্যাকপ্রেস আচরণ পরিচালনা করে এবং কৌশল প্যাটার্নটি ব্যবহার করে সক্রিয় খণ্ডগুলির মধ্যে স্যুইচ করছে।

আপনার কারও কারও জন্য হয়ত বিমূর্ত শ্রেণিতে কিছুটা অসুবিধা ...

সংক্ষেপে, লিঙ্কটি থেকে সমাধানটি এরকম হয়:

// Abstract Fragment handling the back presses

public abstract class BackHandledFragment extends Fragment {
    protected BackHandlerInterface backHandlerInterface;
    public abstract String getTagText();
    public abstract boolean onBackPressed();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(!(getActivity()  instanceof BackHandlerInterface)) {
            throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
        } else {
            backHandlerInterface = (BackHandlerInterface) getActivity();
        }
    }

    @Override
    public void onStart() {
        super.onStart();

        // Mark this fragment as the selected Fragment.
        backHandlerInterface.setSelectedFragment(this);
    }

    public interface BackHandlerInterface {
        public void setSelectedFragment(BackHandledFragment backHandledFragment);
    }
}   

এবং ক্রিয়াকলাপে ব্যবহার:

// BASIC ACTIVITY CODE THAT LETS ITS FRAGMENT UTILIZE onBackPress EVENTS 
// IN AN ADAPTIVE AND ORGANIZED PATTERN USING BackHandledFragment

public class TheActivity extends FragmentActivity implements BackHandlerInterface {
    private BackHandledFragment selectedFragment;

    @Override
    public void onBackPressed() {
        if(selectedFragment == null || !selectedFragment.onBackPressed()) {
            // Selected fragment did not consume the back press event.
            super.onBackPressed();
        }
    }

    @Override
    public void setSelectedFragment(BackHandledFragment selectedFragment) {
        this.selectedFragment = selectedFragment;
    }
}

যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত উত্তর পরিবর্তিত হলে লিঙ্কযুক্ত উত্তরগুলি অবৈধ হতে পারে।
বুনমি

বিটিডাব্লু: আপনি যদি সদৃশগুলি শনাক্ত করেন তবে দয়া করে সেগুলিকে ফ্ল্যাগ করুন। ধন্যবাদ.
বুনমি

এটি কি স্টার্টের ভিতরেই সিলেক্টফ্রেগমেন্ট সেট করা গুরুত্বপূর্ণ?
VLeonovs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.