Ответ 1
Теперь, в какой-то момент времени мне нужно определить, какой объект в настоящее время существует
Вызвать findFragmentById()
на FragmentManager
и определить, какой фрагмент находится в вашем контейнере R.id.frameTitle
.
В моем main.xml
у меня
<FrameLayout
android:id="@+id/frameTitle"
android:padding="5dp"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="@drawable/title_bg">
<fragment
android:name="com.fragment.TitleFragment"
android:id="@+id/fragmentTag"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</FrameLayout>
И я устанавливаю объект фрагмента следующим образом
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");
// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Он устанавливает различные типы объектов фрагмента (FragmentType2,FragmentType3,...
) в разное время. Теперь, в какой-то момент, мне нужно определить, какой объект в настоящее время существует.
В коротком мне нужно сделать что-то вроде этого:
Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle
Я попробовал следующее
TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);
и
TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");
Но оба объекта (titleFragmentById и titleFragmentByTag) null
Я что-то пропустил?
Я использую Compatibility Package, r3
и разрабатываю для API level 7
.
findFragmentById()
и findFragmentByTag()
будут работать, если мы установили фрагмент с использованием fragmentTransaction.replace
или fragmentTransaction.add
, но будем return null
, если мы установили объект в xml (как то, что я сделал в моем main.xml
). Я думаю, что в моих XML файлах что-то не хватает.
Теперь, в какой-то момент времени мне нужно определить, какой объект в настоящее время существует
Вызвать findFragmentById()
на FragmentManager
и определить, какой фрагмент находится в вашем контейнере R.id.frameTitle
.
Попробуй это,
Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
это даст текущему фрагменту, тогда вы можете сравнить его с классом фрагментов и делать свои вещи.
if (currentFragment instanceof NameOfYourFragmentClass) {
Log.v(TAG, "find the current fragment");
}
Я думаю, что вы можете использовать событие onAttachFragment, может быть полезно, чтобы поймать, какой фрагмент активен.
@Override
public void onAttachFragment(Fragment fragment) {
// TODO Auto-generated method stub
super.onAttachFragment(fragment);
Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();
}
Думаю, вам следует:
Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");
Причина в том, что вы добавили тег "fragmentTag" к последнему фрагменту, который вы добавили (когда вы вызвали замену).
Вы можете получить список фрагментов и посмотреть на последний.
FragmentManager fm = getSupportFragmentManager();
List<Fragment> fragments = fm.getFragments();
Fragment lastFragment = fragments.get(fragments.size() - 1);
Но иногда (при переходе назад) размер списка остается неизменным, но некоторые из последних элементов являются нулевыми. Так что в списке я итерировал до последнего ненулевого фрагмента и использовал его.
FragmentManager fm = getSupportFragmentManager();
if (fm != null) {
List<Fragment> fragments = fm.getFragments();
if (fragments != null) {
for(int i = fragments.size() - 1; i >= 0; i--){
Fragment fragment = fragments.get(i);
if(fragment != null) {
// found the current fragment
// if you want to check for specific fragment class
if(fragment instanceof YourFragmentClass) {
// do something
}
break;
}
}
}
}
Это самое простое решение и работа для меня.
1.) вы добавляете свой фрагмент
ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();
2.)
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);
if(currentFragment.getTag().equals("fragment_tag"))
{
//Do something
}
else
{
//Do something
}
Возможно, будет поздно, но я надеюсь, что это поможет кому-то другому, а @CommonsWare опубликовал правильный ответ.
FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");
Возможно, самый простой способ:
public MyFragment getVisibleFragment(){
FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
List<Fragment> fragments = fragmentManager.getFragments();
for(Fragment fragment : fragments){
if(fragment != null && fragment.getUserVisibleHint())
return (MyFragment)fragment;
}
return null;
}
Это сработало для меня
Я знаю, что это было какое-то время, но я буду здесь, если это поможет кому-то.
Правильный ответ на данный момент (и выбранный) - тот, что из CommonsWare. У меня была такая же проблема, как и в журнале, следующий
MyFragmentClass fragmentList =
(MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);
хранится при возврате null. Моя ошибка была действительно глупо в моем XML файле:
<fragment
android:tag="@+id/fragementID"
android:name="com.sf.lidgit_android.content.MyFragmentClass"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Ошибка заключалась в том, что у меня был андроид: тег INSTEAD OF android: id.
Вы можете создать поле в родительском классе активности:
public class MainActivity extends AppCompatActivity {
public Fragment fr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
И затем внутри каждого класса фрагмента:
public class SomeFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
((MainActivity) getActivity()).fr = this;
}
В поле 'fr' находится текущий фрагмент Object
Он также работает с popBackStack()
Реакция с помощью Hammer для меня, im используется для управления кнопкой с плавающим действием
final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
Log.d("VIE",String.valueOf(currentFragment));
if (currentFragment instanceof PerfilFragment) {
PerfilEdit(view, fab);
}
}
});
Если вы определяете фрагмент в операции XML layour, то в Activity
убедитесь, что вы вызываете setContentView()
перед вызовом findFragmentById()
.
Если вы используете BackStack... и ТОЛЬКО, если используете задний стек, попробуйте следующее:
rivate Fragment returnToPreviousFragment() {
FragmentManager fm = getSupportFragmentManager();
Fragment topFrag = null;
int idx = fm.getBackStackEntryCount();
if (idx > 1) {
BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
topFrag = fm.findFragmentByTag(entry.getName());
}
fm.popBackStack();
return topFrag;
}
Если вы выходите из AbstractActivity, вы можете использовать метод getFragments():
for (Fragment f : getFragments()) {
if (f instanceof YourClass) {
// do stuff here
}
}