Child snippet from onListItemClick inside viewPager behaves unexpectedly

I have 3 ListFragments processed by a viewPager (driven by a FragmentAdapter) - they work fine. Now when the user clicks on an item in ListFragment # 1, a new fragment should open with details. It behaves strangely like this:

  • Only clicking the list item twice opens the DetailFragment, but debugging shows that the first click actually goes into the DetailFragment, but does not display the view (the view still displays the current ListFragment).

  • After clicking the 2nd time, DetailFragment shows its layout, but not the elements inside it (like TextView, etc.).

  • If the user "accidentally" views the screen when the DetailFragment is displayed, the viewPager sets it instead of the 2nd list. Only when clicking on the DetailFragment view will the viewPager be "reset" to the correct ListFragment for it. Of course, if the user searches the DetailFragment, the next ListFragment viewPager should appear and the DetailFragment should be removed.

Thanks for any advice confusing across Android the odd world of snippets and views :)

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;
    }
}

      

EDIT: Instead, getActivity().getSupportFragmentManager()

I've also tried getChildFragmentManager()

, but it always gives an error: Method getChildFragmentManager()

is undefined for type PlanetFragment.

+3


source to share


1 answer


When you click on the list item, you are actually creating a new fragment of parts and telling the fragment manager to replace the "frag" tag with that fragment. However, you are not telling the view pager to jump to that snippet.

Since you already have a pointer back to your activity, you can use findViewById to find your view pager and then call viewPager.setCurrentItem.

I think you can be asking problems by creating a new piece of parts inside a list piece. When you use a FragmentPagerAdapter, the adapter usually creates fragments. I would accomplish this by letting the adapter make fragments and then in your onListItemClick find a fragment of the existing details and call a method on it to set it up with the new data. But maybe only setCurrentItem will fix your problem.

EDIT

I'll write your FragmentPagerAdapter first so you can use getItem to retrieve an existing Fragment without creating a new one every time.



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;
    }
}

      

Also add functions to your activity to work with your fragments:

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
}

      

Now when you click on an item in your list snippet, you can get a snippet of an existing part, customize it, and set the ViewPager to display the part snippet.

@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);
}

      

0


source







All Articles