来自viewPager中的onListItemClick的子片段意外行为

时间:2014-11-27 11:06:13

标签: android-fragments android-viewpager android-listfragment onbackpressed

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

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

    < / LI>
  2. 点击第二次后,DetailFragment会显示它的布局,但不显示其中的元素(如TextView等)。

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

  4. 感谢任何有关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类型。

1 个答案:

答案 0 :(得分:0)

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

由于您已经有一个指向活动的后向指针,您可以使用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);
}