在android中显示隐藏片段

abi*_*303 87 android show-hide android-fragments

我正在开发包含2个片段的应用程序,我想根据我的需要显示隐藏.以下代码有我的问题的简单示例.这个简单的Fragmentactivity包含1个按钮和一个listfragment.

这个简单的例子完美无瑕.但我对show hide片段不满意.如果删除layout.setVisibility(View.GONE); 从代码然后ft.hide(f); 不会隐藏片段.实际上我们并没有隐藏我们隐藏容器的片段.

我的问题是,这是一种显示隐藏片段的方法吗?如果没有,那么请用测试的例子解释如何隐藏和显示碎片,因为很多人都面临这个问题.

 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
        }
Run Code Online (Sandbox Code Playgroud)

num*_*ati 149

不要搞乱容器的可见性标志 - FragmentTransaction.hide/show会在内部为您执行此操作.

所以正确的方法是:

FragmentManager fm = getFragmentManager();
fm.beginTransaction()
          .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
          .show(somefrag)
          .commit();
Run Code Online (Sandbox Code Playgroud)

或者如果您使用的是android.support.v4.app.Fragment

 FragmentManager fm = getSupportFragmentManager();
 fm.beginTransaction()
          .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
          .show(somefrag)
          .commit();
Run Code Online (Sandbox Code Playgroud)

  • 你为什么建议不要直接搞乱旗帜?(我不是在质疑你的推荐,只是试图理解它.) (5认同)
  • 它很容易出错,因为你可以在低级API和高级api上改变你的标志,如果你不小心(即标志不同步),你可能会追逐奇怪的错误.这就是为什么它建议使用片段管理器来隐藏和显示你的片段. (2认同)

Ari*_*rià 54

另外,您可以在片段中进行操作(例如,在获取服务器数据失败时):

 getView().setVisibility(View.GONE);
Run Code Online (Sandbox Code Playgroud)

  • Fragment是Object的子节点而不是View,因此无法调用:fragment.setVisibility(View.INVISIBLE); (10认同)
  • 当初始化尚未初始化时,小心的`getView()`可能是`null`. (10认同)
  • Arià建议不同的东西,建议从该片段获取视图并将其可见性设置为消失. (8认同)

小智 19

嗨,你通过使用这种方法做到这一点,所有片段将保留在最初添加的容器中,然后我们只是揭示所需的片段并将其他片段隐藏在容器中.

// 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();
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments.我希望我能帮助任何人.即使这是一个老问题.


Jyo*_*iff 7

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();
}
Run Code Online (Sandbox Code Playgroud)


Ing*_*ngo 6

尝试这个:

MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.mapview);
mapFragment.getView().setVisibility(View.GONE);
Run Code Online (Sandbox Code Playgroud)


Moh*_*hat 5

我可能已经太晚了,但它可以帮助将来的某人。这个答案是对答案
的修改, 我只添加了一个 for 循环以避免重复并轻松添加更多片段而无需样板代码。 mangu23

我们首先需要一个应该显示的 片段列表

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

然后我们需要用我们的片段填充它

@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);
}
Run Code Online (Sandbox Code Playgroud)

我们需要一种方法来知道从列表中选择了哪个片段,所以我们需要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;
}
Run Code Online (Sandbox Code Playgroud)

最后,该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();
    }
Run Code Online (Sandbox Code Playgroud)

这样我们就可以调用displayFragment(homeFragment)例子了。
这将自动显示HomeFragment并隐藏列表中的任何其他片段。
此解决方案允许您向 附加更多片段,而fragmentList无需重复ifdisplayFragment版本中的语句。
我希望有人会觉得这很有用。