Android Fragment How to navigate from custom listview baseadapter to Fargment?

1.1k views Asked by At

I want to ask how to navigate from Listview BaseAdapter to Fragment? I clicked any item and get position and info from it and send to Fragment. How can I do it?

My BaseAdapter:

public class ListViewAdapter extends BaseAdapter {

// Declare Variables
Context context;
LayoutInflater inflater;
ArrayList<HashMap<String, String>> data;
ImageLoader imageLoader;
HashMap<String, String> resultp = new HashMap<String, String>();

public ListViewAdapter(Context context,
        ArrayList<HashMap<String, String>> arraylist) {
    this.context = context;
    data = arraylist;
    imageLoader = new ImageLoader(context);
}

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

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

public View getView(final int position, View convertView, ViewGroup parent) {
    // Declare Variables
    TextView country, rank;
    // TextView population;
    ImageView flag;

    inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View itemView = inflater.inflate(R.layout.listview_item, parent, false);
    // Get the position
    resultp = data.get(position);

    // Locate the TextViews in listview_item.xml
    rank = (TextView) itemView.findViewById(R.id.rank);
    country = (TextView) itemView.findViewById(R.id.country);
    // Locate the ImageView in listview_item.xml
    flag = (ImageView) itemView.findViewById(R.id.flag);

    // Capture position and set results to the TextViews
    distance.setText(resultp.get(FragmentPlaces.RANK));
    bar_name.setText(resultp.get(FragmentPlaces.COUNTRY));
    // population.setText(resultp.get(MainActivity.POPULATION));
    // Capture position and set results to the ImageView
    // Passes flag images URL into ImageLoader.class
    imageLoader.DisplayImage(resultp.get(FragmentPlaces.FLAG), logo_image);
    // Capture ListView item click
    itemView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // // Get the position
            resultp = data.get(position);

            Bundle bundle = new Bundle();
            bundle.putString("rank", resultp.get(FragmentPlaces.RANK));
            bundle.putString("country",
                    resultp.get(FragmentPlaces.COUNTRY));
            bundle.putString("flag", resultp.get(FragmentPlaces.FLAG));
            // set Fragmentclass Arguments
            FragmentSubVenues fragSubVenues = new FragmentSubVenues();
            fragSubVenues.setArguments(bundle);
            // FragmentTransaction ft =
            // getFragmentManager().beginTransaction();
            // ft.replace(R.id.activity_main_content_fragment,
            // fragSubVenues);
            // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            // ft.addToBackStack(null);
            // ft.commit();
            // FragmentManager fragmentManager =
            // activity.getFragmentManager();

        }
    });
    return itemView;
}
}

I want to navigate below Fragment:

  public FragmentSubVenues() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_subview, null);
    Bundle bundle = this.getArguments();
    if(bundle != null){
        bar_name = bundle.getString("country");
        bar_name = bundle.getString("rank");
        bar_name = bundle.getString("flag");
    }

    TextView txtrank = (TextView) view.findViewById(R.id.rank);
    TextView txtcountry = (TextView) view.findViewById(R.id.country);
    ImageView imgflag = (ImageView) view.findViewById(R.id.flag);
    txtrank.setText(country);
    txtcountry.setText(rank);
    imageLoader.DisplayImage(flag, imgflag);

    return view;
}

}

1

There are 1 answers

2
Qianqian On BEST ANSWER

You can define an interface (listener) in your adapter and implement the listener in your activity or fragment.

Please note that you can directly set an OnItemSelectedListener for the listview instead of setting a onClickListener for each list item. (see the N.B. note at the bottom as well)

If you are going to do it in your current fashion anyway, here is some example code based on your current code:

public class ListViewAdapter extends BaseAdapter {

public interface OnItemSelectedListener {
    public void onSelected(String country, String rank, String flag);
}
private OnItemSelectedListener mListener;
// Declare Variables
Context context;
LayoutInflater inflater;
...

And you need to provide a method to set the listener in the adapter class, which is simply to assign the listener implementation to mListener:

public void setOnSelectedListener(OnItemSelectedListener l) {
    mListener = l;
}

In your original code where you was trying to start the fragment, call the listener's method:

public View getView(final int position, View convertView, ViewGroup parent) {
....
itemView.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
       if(mListener!=null) {
           resultp = data.get(position);
           mListener.onSelected(resultp.get(FragmentPlaces.COUNTRY),
               resultp.get(FragmentPlaces.RANK), 
               resultp.get(FragmentPlaces.FLAG));
       }
    ....

And move your fragment start code into your activity or main fragment, which implements the defined interface.

Note: You are not using the convertView passed to getView method of your adapter, this is generally not good for listview/gridview. You can search ListView Adapter convertView in Google, and you will find plenty of articles introducing it.

NB: You do not need to set the OnClickListener for each view of your list item really. Instead you can directly set OnItemClickListener for the ListView, and switch the fragment there. I think this is much better than what you are currently doing. This will save you much extra code. And you may not need to define an interface.

EDIT: Example of using OnItemClickListener

Basically you can set the listener as below in onCreate (If you use it in activity) or onCreateView (if you use it in another fragment)

...
mAdapter = new ListViewAdapter(...);
ListView yourListView = (ListView)findViewById(R.id.your_list_view_id);
yourListView.setAdapter(mAdapter);
yourListView.setOnItemClickListener( new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        HashMap<String, String> resultp = mAdapter.getItem(position);
        // Switch to the fragment you want with the information you can get from resultp
        ...
    }
});

The switchFragment is the method where you start the new fragment, you can write that method