Programing

조각 백 스택으로 ActionBar 제목을 처리합니까?

lottogame 2020. 10. 26. 07:36
반응형

조각 백 스택으로 ActionBar 제목을 처리합니까?


내가 Activity로드 위치가 ListFragment있고, 클릭하면 레벨을 드릴 다운하고 새 유형 ListFragment이 표시되어 원본을 대체합니다 ( showFragment아래 방법 사용 ). 이것은 백 스택에 배치됩니다.

처음에 활동은 작업 표시 줄에 기본 제목을 표시합니다 (예 : 애플리케이션의를 기반으로 자동 설정 됨 android:label).

계층 구조에서 다음 수준에 대한 목록을 표시 할 때 클릭 한 항목의 이름이 작업 표시 줄의 제목이되어야합니다.

그러나를 누르면 Back원래의 기본 제목이 복원되기를 원합니다. 이것은 FragmentTransaction아는 것이 아니므로 제목이 복원되지 않습니다.

에 대해 모호하게 읽었 FragmentBreadCrumbs지만 사용자 정의보기를 사용해야하는 것 같습니다. ActionBarSherlock을 사용하고 있으며 내 사용자 지정 제목보기가없는 것을 선호합니다.

이를 수행하는 가장 좋은 방법은 무엇입니까? 상용구 코드를 많이 사용하지 않고 길을 따라 표시된 제목을 추적 할 필요없이 가능합니까?


protected void showFragment(Fragment f) {
  FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  ft.replace(R.id.fragment_container, f);
  ft.addToBackStack(null);
  ft.commit();
}

모든 조각과 모든 활동에서 나는 이와 같이 제목을 변경합니다. 이렇게하면 활성 제목이 항상 정확합니다.

@Override
public void onResume() {
    super.onResume();
    // Set title
    getActivity().getActionBar()
        .setTitle(R.string.thetitle);
}

조각 내에서 onResume이 호출되지 않는 경우가 있습니다. 이러한 경우 중 일부에서는 다음을 사용할 수 있습니다.

public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser) {
        // Set title
        getActivity().getActionBar()
            .setTitle(R.string.thetitle);
    }
}

원래 답변이 꽤 오래 되었기 때문에 도움이 될 수도 있습니다. 문서에 나와 있듯이 listener호스팅에서 백 스택 변경 사항을 수신 하기 위해 a 등록 할 수 있습니다 Activity.

getSupportFragmentManager().addOnBackStackChangedListener(
        new FragmentManager.OnBackStackChangedListener() {
            public void onBackStackChanged() {
                // Update your UI here.
            }
        });

그런 다음 콜백 메서드에서 상황을 식별하고에서에 액세스하지 않고 적절한 제목을 설정 ActionBar합니다 Fragment.

이것은 존재 Fragment에 대해 알 필요가 없으며 일반적으로 백 스택을 관리하는 장소이므로 더 우아한 솔루션으로 처리하는 것이 더 적절 해 보입니다. 항상 주변 환경이 아닌 자체 콘텐츠로만 고려되어야합니다.ActionBarActivityFragment

문서 의 주제에 대해 자세히 알아보십시오 .


제어 활동이 다음과 같이 모든 작업을 수행하도록하십시오.

백 스택 이벤트 수신 (활동 onCreate ()에서) :

// Change the title back when the fragment is changed
    getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fragment = getFragment();
            setTitleFromFragment(fragment);
        }
    });

컨테이너에서 현재 조각을 가져옵니다.

/**
 * Returns the currently displayed fragment.
 * @return
 *      Fragment or null.
 */
private Fragment getFragment() {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container);
    return fragment;
}

콘텐츠보기 내에서 조각을 설정합니다.

private void setFragment(Fragment fragment, boolean addToBackStack) {
    // Set the activity title
    setTitleFromFragment(fragment);
    .
    .
    .
}

Warpzit이 맞습니다. 이것은 또한 장치의 방향이 변경 될 때 제목 문제를 해결합니다. 또한 작업 표시 줄에 지원 v7을 사용하는 경우 다음과 같이 조각에서 작업 표시 줄을 가져올 수 있습니다.

@Override
public void onResume() {
    super.onResume();
    ((ActionBarActivity)getActivity()).getSupportActionBar().setTitle("Home");
}

OS가 가능한 한 많은 작업을 수행하도록하는 것이 가장 좋습니다. .addToBackStack ( "title")을 사용하여 각 조각의 이름이 적절하게 지정되었다고 가정하면 다음과 같이 onBackPressed를 재정 의하여 원하는 동작을 얻을 수 있습니다.

// this example uses the AppCompat support library
// and works for dynamic fragment titles
@Override
public void onBackPressed() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    int count = fragmentManager.getBackStackEntryCount();
    if (count <= 1) {
        finish();
    }
    else {
        String title = fragmentManager.getBackStackEntryAt(count-2).getName();
        if (count == 2) {
            // here I am using a NavigationDrawer and open it when transitioning to the initial fragment
            // a second back-press will result in finish() being called above.
            mDrawerLayout.openDrawer(mNavigationDrawerFragment.getView());
        }
        super.onBackPressed();
        Log.v(TAG, "onBackPressed - title="+title);
        getSupportActionBar().setTitle(title);
    }
}

나는 Lee 접근 방식 과 유사한 솔루션을 사용 하지만 대신 onBackStackChanged()방법을 대체 합니다.

먼저 백 스택에 트랜잭션을 추가 할 때 조각 이름을 설정했습니다.

getSupportFragmentManager().beginTransaction()
                .replace(R.id.frame_content, fragment)
                .addToBackStack(fragmentTitle)
                .commit();

그런 다음 onBackStackChanged()메서드를 재정의하고 setTitle()마지막 백 스택 항목 이름으로 호출 합니다.

@Override
public void onBackStackChanged() {
    int lastBackStackEntryCount = getSupportFragmentManager().getBackStackEntryCount() - 1;
    FragmentManager.BackStackEntry lastBackStackEntry =
            getSupportFragmentManager().getBackStackEntryAt(lastBackStackEntryCount);

    setTitle(lastBackStackEntry.getName());
}

조각 방법 사용 :

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)

모든 Fragment 모양에 대해 호출되지만 onResume은 그렇지 않습니다.


가장 좋은 방법은 Android에서 제공하는 Interface OnBackStackChangedListener 메서드 onBackStackChanged ()를 사용하는 것입니다.

사용자가 탐색 할 수있는 4 가지 옵션이있는 탐색 창이 있다고 가정 해 보겠습니다. 이 경우 4 개의 조각이 있습니다. 먼저 코드를 살펴본 다음 작동 방식을 설명하겠습니다.

    private int mPreviousBackStackCount = 0;
    private String[] title_name = {"Frag1","Frag2","Frag3","Frag4"};
    Stack<String> mFragPositionTitleDisplayed;

    public class MainActivity extends ActionBarActivity implements FragmentManager.OnBackStackChangedListener
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ....
    ....
    ....
    getSupportFragmentManager().addOnBackStackChangedListener(this);
    mFragPositionTitleDisplayed = new Stack<>();
}

public void displayFragment() {
    Fragment fragment = null;
    String title = getResources().getString(R.string.app_name);
    switch (position) {
        case 0:
            fragment = new Fragment1();
            title = title_name[position];
            break;
        case 1:
            fragment = new Fragment2();
            title = title_name[position];
            break;
        case 2:
            fragment = new Fragment3();
            title = title_name[position];
            break;
        case 3:
            fragment = new Fragment4();
            title = title_name[position];
            break;
        default:
            break;
    }
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container_body, fragment)
                .addToBackStack(null)
                .commit();
        getSupportActionBar().setTitle(title);
    }
}

@Override
public void onBackStackChanged() {
    int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
    if(mPreviousBackStackCount >= backStackEntryCount) {
        mFragPositionTitleDisplayed.pop();
        if (backStackEntryCount == 0)
            getSupportActionBar().setTitle(R.string.app_name);
        else if (backStackEntryCount > 0) {
            getSupportActionBar().setTitle(mFragPositionTitleDisplayed.peek());
        }
        mPreviousBackStackCount--;
    }
    else{
        mFragPositionTitleDisplayed.push(title_name[position]);
        mPreviousBackStackCount++;
    }

}   

표시된 코드에는 displayFragment () 메서드가 있습니다. 여기에서는 탐색 창에서 선택한 옵션을 기준으로 조각을 표시합니다. 변수 위치는 탐색 창에서 ListView 또는 RecyclerView에서 클릭 한 항목의 위치에 해당합니다. 이에 따라 getSupportActionBar.setTitle (title)을 사용하여 작업 표시 줄 제목을 설정했습니다. 여기서 제목은 적절한 제목 이름을 저장합니다.

Whenever we click the item from nav drawer a fragment is displayed depending on the item clicked to the user. But on the back end side this fragment is added to the backstack and the method onBackStachChanged(), gets hit. What I have done is that I have created a variable mPreviousBackStackCount and initialized it to 0. I have also created an additional stack which will store the action bar title names. Whenever I add a new fragment to the backstack, I add the corresponding title name to my created stack. On the opposite side whenever I press the back button onBackStackChanged() is called and I pop the last title name from my stack and set the title to the name derived by the peek() method of the stack.

Example:

Lets say our android backstack is empty:

Press Choice 1 from nav drawer: onBackStachChanged() is called and the Fragment 1 is added to android backstack, backStackEntryCount is set to 1 and Frag1 is pushed to my stack and size of mFragPositionTitleDisplayed becomes 1.

Press Choice 2 from nav drawer: onBackStachChanged() is called and the Fragment 2 is added to android backstack, backStackEntryCount is set to 2 and Frag2 is pushed to my stack and size of mFragPositionTitleDisplayed becomes 2.

Now we have 2 elements both in the android stack and my stack. When you press back button onBackStackChanged() is called and the value of backStackEntryCount is 1. The code enters the if part and pops out the last entry from my stack. So, the android backstack has only 1 fragment - "Fragment 1" and my stack has only 1 title - "Frag1". Now I just peek() the title from my stack and set the action bar to that title.

Remember: To set the action bat title use peek() and not pop() else your application will crash when you open more than 2 fragments and try to go back by pressing back button.


You cane Solve with onKeyDown! I have a bool mainisopen=true <-- MainFragment is Visible other Fragment mainisopen=false

and here is My Code:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == false) {
        mainisopen = true;
        HomeFrag fragment = new HomeFrag();
        FragmentTransaction fragmentTransaction =
                getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragmet_cont, fragment);
        fragmentTransaction.commit();
        navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.getMenu().findItem(R.id.nav_home).setChecked(true);
        navigationView.setNavigationItemSelectedListener(this);
        this.setTitle("Digi - Home"); //Here set the Title back
        return true;
    } else {
        if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == true) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("Wollen sie die App schliessen!");
            builder.setCancelable(true);

            builder.setPositiveButton("Ja!", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    System.exit(1);
                }
            });

            builder.setNegativeButton("Nein!", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_SHORT).show();
                }
            });

            AlertDialog dialog = builder.create();
            dialog.show();

            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}

As described here my solution is adding this code to MainActivity onCreate method(): and changing actionbar title

FragmentManager fragmentManager=getSupportFragmentManager();
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
    @Override
    public void onBackStackChanged() {
        Fragment currentFragment = fragmentManager.findFragmentById(R.id.My_Container_1_ID);
        currentFragment.onResume();
    }
});

and changing actionbar title in fragment's onResume() method

@Override
public void onResume() {
    super.onResume();
    AppCompatActivity activity = (AppCompatActivity) getActivity();
    ActionBar actionBar = activity.getSupportActionBar();
    if(actionBar!=null) {
        actionBar.setTitle("Fragment Title");
        actionBar.setSubtitle("Subtitle");
    }

}

To update the actionbar title on back press. Just simply put

getActivity.setTitle("title")

inside onCreateView method.

참고URL : https://stackoverflow.com/questions/13472258/handling-actionbar-title-with-the-fragment-back-stack

반응형