Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android how to open fragment from listview element

In MainActivity is FrameLayout MainContainer. I load there a fragment TrainerMyGroups, there is a Listview where I add a few elements (each element has some strings) by use TrainerGroupsAdapter. Actually I want to replace fragment TrainerMyGroups by another (for example TrainersInfo) by click on list's element.

My TrainerGroupsAdapter is:

public class TrainerGroupsAdapter extends ArrayAdapter {

    List list = new ArrayList();

    public TrainerGroupsAdapter(Context context, int resource) {
        super(context, resource);
    }

    static class Datahandler{
        TextView name;
        TextView when;
        TextView where;
        LinearLayout ll;
    }

    @Override
    public void add(Object object) {
        super.add(object);
        list.add(object);
    }

    @Override
    public int getCount() {
        return this.list.size();
    }

    @Override
    public Object getItem(int position) {
        return this.list.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        row=convertView;
        Datahandler handler;
        SharedPreferences pref = getContext().getSharedPreferences("pref", Context.MODE_PRIVATE);

        if(convertView==null){
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row= inflater.inflate(R.layout.list_mygroups,parent,false);
            handler = new Datahandler();
            handler.name =  (TextView) row.findViewById(R.id.trainermygroupslistname);
            handler.where =  (TextView) row.findViewById(R.id.trainermygroupslistwhere);
            handler.when =  (TextView) row.findViewById(R.id.trainermygroupslistwhen);
            handler.ll=(LinearLayout) row.findViewById(R.id.trainermygroupslistlayout);
            row.setTag(handler);
        }
        else {
            handler = (Datahandler)row.getTag();
        }

        TrainerGroupsDataProvider dataProvider;
        dataProvider = (TrainerGroupsDataProvider)this.getItem(position);
        handler.name.setText(dataProvider.getName());
        handler.when.setText(dataProvider.getWhen());
        handler.where.setText(dataProvider.getWhere());
        handler.ll.setBackgroundColor(Color.parseColor(pref.getString(TRANSP_KEY, "#CC") + dataProvider.getColor()));


        handler.ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
            }
        });


        return row;
    }

}

It doesn't work but method OnClick is probably good because if I replace getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit(); to code for change some strings (name, when tc) it works. Problem is in getFragmentMenager(), Android Studio shows message that I have to create Getter and AS's suggestion is to generate in OnClick method:

private FragmentManager fragmentManager;
public FragmentManager getFragmentManager() {
      return fragmentManager;
}

then problem is in the second argument in replace, I have error that it has to be Fragment (Im sure that TrainersInfo() is fragment because I use it in other place and it works). How can I solve this problem or what is the best way to open fragment by click on lise's element in another fragment?

like image 724
barmi Avatar asked Apr 30 '16 21:04

barmi


People also ask

How do you open a fragment by adding a click on list?

First, instead of using "add", use "replace". If there is no fragment in fragment manager, your fragment will be added, instead it will be replaced. If you use "add", then you could accidentally add more than one fragment. You should check for the fragment in the fragment manager and call methods for content updates.

How to get data from ListView by Clicking item on ListView?

Try this: my_listview. setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { } });

How to load Fragment in Android?

Add a fragment to an activity You can add your fragment to the activity's view hierarchy either by defining the fragment in your activity's layout file or by defining a fragment container in your activity's layout file and then programmatically adding the fragment from within your activity.


1 Answers

#UPDATE2

Better then replacing the Fragment inside the adapter is to say your activity that it should replace the fragment. This can be done with an interface which you implement inside your Activity:

public class TrainerGroupsAdapter extends ArrayAdapter {
    // The interface which you have to implement in your activity
    public interface OnChangeFragmentListener {
        void changeFragment();
    }

    List list = new ArrayList();
    private OnChangeFragmentListener m_onChangeFragmentListener;

    public TrainerGroupsAdapter(Context context, int resource) {
        super(context, resource);
        m_onChangeFragmentListener = (OnChangeFragmentListener) context;
    }

    // Your other code

}

The OnClickListener in your getView Method:

handler.ll.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Call the method which change the fragment
        m_onChangeFragmentListener.changeFragment();
    }
});

The Activity:

public class MainActivity extends AppCompatActivity implements TrainerGroupsAdapter.OnChangeFragmentListener {

    //...
    //  Your Other code

    // Implement the method which is called in the adapter and replace the fragment here
    @Override
    public void changeFragment() {
        getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
    }
}

#UPDATE1

You need an activity context for getSupportFragmentManager() and getFragmentManager(). You can change the Context parameter of the constructor to Activity and create a member variable in your class for the activity so you can use it later:

public class TrainerGroupsAdapter extends ArrayAdapter {

    List list = new ArrayList();
    private Activity m_activity;

    public TrainerGroupsAdapter(Activity context, int resource) {
        super(context, resource);
        m_activity = context;
    }
    // Your other code
}

The OnClickListener in your getView method:

   handler.ll.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            m_activity.getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
        }
   });
like image 198
TmCrafz Avatar answered Oct 14 '22 15:10

TmCrafz