简体   繁体   English

在android中显示隐藏片段

[英]Show hide fragment in android

I am developing application which contains 2 fragments and i want to show hide according to my need.我正在开发包含 2 个片段的应用程序,我想根据需要显示隐藏。 Following code has simple example of my problem.以下代码有我的问题的简单示例。 This simple Fragmentactivity contains 1 button and one listfragment.这个简单的 Fragmentactivity 包含 1 个按钮和一个列表片段。

This simple example works flawless.这个简单的例子完美无缺。 but i am not satisfied with show hide fragment.但我对显示隐藏片段不满意。 If you remove layout.setVisibility(View.GONE);如果删除 layout.setVisibility(View.GONE); from the code then ft.hide(f);从代码然后 ft.hide(f); will not hide fragment.不会隐藏片段。 In fact we are not hiding fragment we are hiding container.事实上,我们不是在隐藏片段,而是在隐藏容器。

My Question is, IS this a way to show hide fragments?我的问题是,这是一种显示隐藏片段的方式吗? If not then please explain with tested example How to hide and show Fragments because lots of people are facing this problem.如果没有,请用经过测试的示例解释如何隐藏和显示片段,因为很多人都面临这个问题。

 public class MainActivity extends FragmentActivity implements OnClickListener {

        Fragment1 f;
        Button b;
        LinearLayout layout;
        Fragment myf;
        @Override
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            b = (Button) findViewById(R.id.button1);
            layout = (LinearLayout) findViewById(R.id.ll);
            f = new Fragment1();
        }

        @Override
        public void onClick(View v) {

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);

            if (f.isHidden()) {
                ft.show(f);
                layout.setVisibility(View.VISIBLE);
                b.setText("Hide");
            } else {
                ft.hide(f);
                b.setText("Show");
                layout.setVisibility(View.GONE);
            }
            ft.commit();
            // TODO Auto-generated method stub
        }

Don't mess with the visibility flags of the container - FragmentTransaction.hide/show does that internally for you.不要弄乱容器的可见性标志 - FragmentTransaction.hide/show 在内部为你做这件事。

So the correct way to do this is:所以正确的做法是:

FragmentManager fm = getFragmentManager();
fm.beginTransaction()
          .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
          .show(somefrag)
          .commit();

OR if you are using android.support.v4.app.Fragment或者,如果您使用的是 android.support.v4.app.Fragment

 FragmentManager fm = getSupportFragmentManager();
 fm.beginTransaction()
          .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
          .show(somefrag)
          .commit();

此外,您可以在 Fragment 中执行以下操作(例如,当获取服务器数据失败时):

 getView().setVisibility(View.GONE);

Hi you do it by using this approach, all fragments will remain in the container once added initially and then we are simply revealing the desired fragment and hiding the others within the container.嗨,您使用这种方法来做到这一点,一旦最初添加,所有片段将保留在容器中,然后我们只是显示所需的片段并将其他片段隐藏在容器中。

// Within an activity
private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        fragmentA = FragmentA.newInstance("foo");
        fragmentB = FragmentB.newInstance("bar");
        fragmentC = FragmentC.newInstance("baz");
    }
}


// Replace the switch method
protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}

Please see https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments for more info.请参阅https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments了解更多信息。 I hope I get to help anyone.我希望我能帮助任何人。 Even if it this is an old question.即使这是一个老问题。

Try this:试试这个:

MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.mapview);
mapFragment.getView().setVisibility(View.GONE);
public void showHideFragment(final Fragment fragment){

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.setCustomAnimations(android.R.animator.fade_in,
                    android.R.animator.fade_out);

    if (fragment.isHidden()) {
        ft.show(fragment);
        Log.d("hidden","Show");
    } else {
        ft.hide(fragment);
        Log.d("Shown","Hide");                        
    }

    ft.commit();
}

I may be way way too late but it could help someone in the future.我可能来得太晚了,但它可以帮助将来的某个人。
This answer is a modification to mangu23 answer这个答案是对mangu23答案的修改
I only added a for loop to avoid repetition and to easily add more fragments without boilerplate code.我只添加了一个 for 循环以避免重复并轻松添加更多片段而无需样板代码。

We first need a list of the fragments that should be displayed我们首先需要一个应该显示的片段列表

public class MainActivity extends AppCompatActivity{
    //...
    List<Fragment> fragmentList = new ArrayList<>();
}

Then we need to fill it with our fragments然后我们需要用我们的片段填充它

@Override
protected void onCreate(Bundle savedInstanceState) {
    //...
    HomeFragment homeFragment = new HomeFragment();
    MessagesFragment messagesFragment = new MessagesFragment();
    UserFragment userFragment = new UserFragment();
    FavoriteFragment favoriteFragment = new FavoriteFragment();
    MapFragment mapFragment = new MapFragment();

    fragmentList.add(homeFragment);
    fragmentList.add(messagesFragment);
    fragmentList.add(userFragment);
    fragmentList.add(favoriteFragment);
    fragmentList.add(mapFragment);
}

And we need a way to know which fragment were selected from the list, so we need getFragmentIndex function我们需要一种方法来知道从列表中选择了哪个片段,所以我们需要getFragmentIndex函数

private int getFragmentIndex(Fragment fragment) {
    int index = -1;
    for (int i = 0; i < fragmentList.size(); i++) {
        if (fragment.hashCode() == fragmentList.get(i).hashCode()){
            return i;
        }
    }
    return index;
}

And finally, the displayFragment method will like this:最后, displayFragment方法将是这样的:

private void displayFragment(Fragment fragment) {
        int index = getFragmentIndex(fragment);
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (fragment.isAdded()) { // if the fragment is already in container
            transaction.show(fragment);
        } else { // fragment needs to be added to frame container
            transaction.add(R.id.placeholder, fragment);
        }
        // hiding the other fragments
        for (int i = 0; i < fragmentList.size(); i++) {
            if (fragmentList.get(i).isAdded() && i != index) {
                transaction.hide(fragmentList.get(i));
            }
        }
        transaction.commit();
    }

In this way, we can call displayFragment(homeFragment) for example.这样,我们可以调用displayFragment(homeFragment)为例。
This will automatically show the HomeFragment and hide any other fragment in the list.这将自动显示HomeFragment并隐藏列表中的任何其他片段。
This solution allows you to append more fragments to the fragmentList without having to repeat the if statements in the old displayFragment version.此解决方案允许您将更多片段附加到fragmentList而无需重复旧displayFragment版本中的if语句。
I hope someone will find this useful.我希望有人会发现这很有用。

From my code, comparing to above solution, the simplest way is to define a layout which contains the fragment, then you could hide or unhide the fragment by controlling the layout attribute which is align with the general way of view.从我的代码中,与上述解决方案相比,最简单的方法是定义一个包含片段的布局,然后您可以通过控制与一般视图对齐的布局属性来隐藏或取消隐藏片段。 No additional code needed in this case and the additional deployment attributes of the fragment could be moved to the outer layout.在这种情况下不需要额外的代码,片段的额外部署属性可以移动到外部布局。

<LinearLayout style="@style/StHorizontalLinearView"
    >

    <fragment
        android:layout_width="match_parent"
        android:layout_height="390dp"
        android:layout_alignParentTop="true"
        />

</LinearLayout>
final Fragment fragment1 = new fragment1();
final Fragment fragment2 = new fragment2();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;

In onCreate, after setContentView, i hid two fragments and committed them to the fragment manager, but i didn't hide the first fragment that will serve as home.在 onCreate 中,在 setContentView 之后,我隐藏了两个片段并将它们提交给片段管理器,但我没有隐藏将用作主页的第一个片段。

fm.beginTransaction().add(R.id.main_container, fragment2, "2").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container,fragment1, "1").commit();
 @Override
    public void onClick(View v) {
        Fragment another = fragment1;
         if(active==fragment1){
          another = fragment2;
         }
            fm.beginTransaction().hide(active).show(another).commit();
            active = another;
}

Ref : https://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711参考: https : //medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711

This worked for me这对我有用

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        if(tag.equalsIgnoreCase("dashboard")){

            DashboardFragment dashboardFragment = (DashboardFragment)
                    fragmentManager.findFragmentByTag("dashboard");
            if(dashboardFragment!=null) ft.show(dashboardFragment);

            ShowcaseFragment showcaseFragment = (ShowcaseFragment)
                    fragmentManager.findFragmentByTag("showcase");
            if(showcaseFragment!=null) ft.hide(showcaseFragment);

        } else if(tag.equalsIgnoreCase("showcase")){
            DashboardFragment dashboardFragment = (DashboardFragment)
                    fragmentManager.findFragmentByTag("dashboard");
            if(dashboardFragment!=null) ft.hide(dashboardFragment);

            ShowcaseFragment showcaseFragment = (ShowcaseFragment)
                    fragmentManager.findFragmentByTag("showcase");
            if(showcaseFragment!=null) ft.show(showcaseFragment);
        }

        ft.commit();

the answers here are correct and i liked @Jyo the Whiff idea of a show and hide fragment implementation except the way he has it currently would hide the fragment on the first run so i added a slight change in that i added the isAdded check and show the fragment if its not already这里的答案是正确的,我喜欢@Jyo 显示和隐藏片段实现的 Whiff 想法,除了他目前拥有的方式会在第一次运行时隐藏片段,所以我添加了一个细微的变化,因为我添加了 isAdded 检查和显示片段(如果还没有)

public void showHideCardPreview(int id) {
    FragmentManager fm = getSupportFragmentManager();
    Bundle b = new Bundle();
    b.putInt(Constants.CARD, id);
    cardPreviewFragment.setArguments(b);
    FragmentTransaction ft = fm.beginTransaction()
        .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    if (!cardPreviewFragment.isAdded()){
        ft.add(R.id.full_screen_container, cardPreviewFragment);
        ft.show(cardPreviewFragment);
    } else {
        if (cardPreviewFragment.isHidden()) {
            Log.d(TAG,"++++++++++++++++++++ show");
            ft.show(cardPreviewFragment);
        } else {
            Log.d(TAG,"++++++++++++++++++++ hide");
            ft.hide(cardPreviewFragment);
        }
    }

    ft.commit();
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM