3

我有 3 个 ListFragments 由 viewPager 处理(由 FragmentAdapter 管理) - 它们工作得很好。现在,当用户单击 ListFragment #1 中的项目时,应该会打开一个包含详细信息的新 Fragment。它以以下方式表现得很奇怪:

  1. 仅单击列表项两次打开 DetailFragment,但调试显示第一次单击确实进入了 DetailFragment,但不显示视图(视图仍显示当前的 ListFragment)。

  2. 单击第二次后,DetailFragment 确实显示了它的布局,但不显示其中的元素(如 TextView 等)。

  3. 如果在显示 DetailFragment 时用户“意外”滑动屏幕,viewPager 会将其设置为第二个 ListFragment!只有在 DetailFragment 视图上按回时,才会将 viewPager“重置”为正确的 ListFragment。当然,如果用户在一个 DetailFragment 中滑动,应该会出现 viewPager 的下一个 ListFragment,并且应该删除 DetailFragment。

感谢您在 Android 奇怪的片段和视图世界中提供的任何提示:)

public class PlanetFragment extends ListFragment{

    LayoutInflater inflater;
    ListView list;
    ArrayList<HashMap<String, String>> planetListArray;

    HashMap<String, String> planetMap;
    Activity activity;
    Context context;

       @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.planets_tab_layout, container, false);
            inflater=(LayoutInflater)getLayoutInflater(savedInstanceState);
            activity = getActivity();
            context = PlanetFragment.this.getActivity();
            String dbTableName = "Table_Planets";
            SQLiteHelper info = new SQLiteHelper(getActivity().getBaseContext());       
            info.open();

            ArrayList<HashMap<String, String>> datafromSQL = info.getData(dbTableName);

            if(!datafromSQL.isEmpty()){ 
                planetListArray = new  ArrayList<HashMap<String, String>>();
                for (int i = 0; i<datafromSQL.size(); i++){

                    planetMap = new HashMap<String, String>();
                    planetMap.put(PLANET_ID, datafromSQL.get(i).get(KEY_PLANET_ID));
                    planetMap.put(ZODIAC_ID, datafromSQL.get(i).get(KEY_ZODIAC_ID));
                    planetMap.put(DEGREES, datafromSQL.get(i).get(KEY_DEGREES));
                    planetMap.put(CONTENT, datafromSQL.get(i).get(KEY_CONTENT));

                    planetListArray.add(planetMap);              
                }   
                info.close();
            }

          list = (ListView) v.findViewById(android.R.id.list); 
          PlanetAdapter adapter=new PlanetAdapter(getActivity(), R.layout.planets_row, planetListArray); 
          list.setAdapter(adapter);

          return v;
       }

       @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            //the dividers 
            getListView().setDivider(getResources().getDrawable(R.drawable.purplebartop));
        }

    @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            super.onListItemClick(l, v, position, id);
            HashMap<String, String> item = planetListArray.get(position);

            Bundle bundle = new Bundle();
            bundle.putSerializable("itemMap", item);
            bundle.putInt("position", position);
            Fragment frag = DetailFragment.newInstance();
            frag.setArguments(bundle);
            if (frag != null) {
                getActivity().getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.pager, frag, "frag")
                    .addToBackStack("frag")
                    .commit();
            }
        }
}



public class DetailFragment extends Fragment{

    Context context;
    Activity activity;
    TextView planetName;

    public static android.support.v4.app.Fragment newInstance() {
        DetailFragment f = new DetailFragment();
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        inflater=(LayoutInflater)getLayoutInflater(savedInstanceState);
        View v = inflater.inflate(R.layout.dialog_details, container, false);
        activity = getActivity();
        context = DetailFragment.this.getActivity();
        planetName = (TextView)v.findViewById(R.id.planetNameExpanded);
        planetName.setText("planetX");

        return v;
    }
}

编辑: 而不是getActivity().getSupportFragmentManager()我也尝试过getChildFragmentManager() ,但它总是给出错误:该方法getChildFragmentManager()对于类型 PlanetFragment 是未定义的。

4

1 回答 1

0

当您单击一个列表项时,您确实在构建一个新的详细信息片段并告诉片段管理器用该片段替换标记“片段”。但是,您并没有告诉视图寻呼机切换到该片段。

由于您已经有一个指向您的活动的反向指针,您可以使用 findViewById 来查找您的视图寻呼机,然后调用 viewPager.setCurrentItem。

我认为您可能会通过在列表片段中构建一个新的详细信息片段来自找麻烦。当您使用 FragmentPagerAdapter 时,适配器通常会构建片段。我会通过让适配器制作片段来实现这一点,然后在您的 onListItemClick 中找到现有的详细信息片段并在其上调用一个方法以使用新数据对其进行配置。但也许只有 setCurrentItem 可以解决您的问题。

编辑

首先,我会编写您的 FragmentPagerAdapter,这样您就可以使用 getItem 来获取现有的片段,而无需每次都创建一个新片段。

public class PlanetFragmentAdapter extends FragmentPagerAdapter {
    private Fragment [] fragments = new Fragments[3];

    public PlanetFragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = fragments[position];

        if (fragment == null) {
            switch (position) {
                case 0:
                    fragment = new PlanetFragment();
                    break;
                case 1:
                    fragment = new DetailFragment();
                    break;
                case 2:
                    fragment = new MysteryFragment();
                    break;
            }
            fragments[position] = fragment;
        }
        return fragment;
    }
}

还要在你的活动中添加函数来处理你的片段:

public void setPage(int position) {
    viewPager.setCurrentItem(position);
}

public DetailFragment getDetailFragment() {
    return (DetailFragment) viewPager.getItem(1); // now it doesn't create a new instance
    // you could also use getSupportFragmentManager().findFragmentById() here
}

现在,当您单击列表片段中的某个项目时,您可以获得现有的详细信息片段,对其进行配置,并将 ViewPager 设置为显示详细信息片段。

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    HashMap<String, String> item = planetListArray.get(position);

    Bundle bundle = new Bundle();
    bundle.putSerializable("itemMap", item);
    bundle.putInt("position", position);
    PlanetActivity pa = (PlanetActivity) activity;
    DetailFragment frag = pa.getDetailFragment();
    frag.setArguments(bundle);
    pa.setCurrentItem(1);
}
于 2014-11-28T09:01:29.227 回答