Basic adapter, how to use convertView when displaying different views

lets say that this is my code, I want to inflate 2 different views in a listView according to some conditions.

public View getView(int position, View convertView, ViewGroup parent) {
    if (condition) {
        view = layoutInflater.inflate(R.layout.layout1, parent, false);
    } else {
        view = layoutInflater.inflate(R.layout.layout2, parent, false);
    }
    return view;
}

I want to use convertView to reuse the returned view, however, how will my adapter know which of the two types to process?

+4
source share
4 answers

Answer:

You must add this method to your adapter, this will force the adapter to give the correct converted look to your current index. It doesn't matter what number you return as long as you stay in the correct type.

public int getItemViewType(int position) {
        int type;
        if (condition) {
            type = 1;
        } else {
            type = 2;
        }
        return type;
    }
+2
source

You need to implement 2 more methods from Adapter:

/**
 * <p>
 * Returns the number of types of Views that will be created by
 * {@link #getView}. Each type represents a set of views that can be
 * converted in {@link #getView}. If the adapter always returns the same
 * type of View for all items, this method should return 1.
 * </p>
 * <p>
 * This method will only be called when when the adapter is set on the
 * the {@link AdapterView}.
 * </p>
 * 
 * @return The number of types of Views that will be created by this adapter
 */
int getViewTypeCount();
/**
 * Get the type of View that will be created by {@link #getView} for the specified item.
 * 
 * @param position The position of the item within the adapter data set whose view type we
 *        want.
 * @return An integer representing the type of View. Two views should share the same type if one
 *         can be converted to the other in {@link #getView}. Note: Integers must be in the
 *         range 0 to {@link #getViewTypeCount} - 1. {@link #IGNORE_ITEM_VIEW_TYPE} can
 *         also be returned.
 * @see #IGNORE_ITEM_VIEW_TYPE
 */
int getItemViewType(int position);

. 2 :

@Override
public int getItemViewType(int position) {
    if(condition(position)){
        return 0;
    }
    return 1;
}

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(condition(position)){
        //handle first type of view 0
    } else {
        //handle second type of view 1
    }
}
0
 private class MyAdapter extends ArrayAdapter<String> {



    public MyAdapter(Context context, List<String> list) {
        super(context, 0, list);
    }

    @Override
    public int getItemViewType(int position) {
        return position % 2;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        int type = getItemViewType(position);
            if (type == 1){
                view = layoutInflater.inflate(R.layout.layout1, parent, false);
            } else {
                view = layoutInflater.inflate(R.layout.layout2, parent, false);
            }
        return view;
    }

}
0

:

Add both views as children of the same layout (item_example.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white">
        <View
            android:id="@+id/v_first"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone">
        <View
            android:id="@+id/v_second"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone">
</LinearLayout>

and decide which one to show at runtime depending on your desired condition:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View exampleView = convertView;

    if (exampleView == null) {
        LayoutInflater inflater = fragment.getActivity().getLayoutInflater();
        exampleView             = inflater.inflate(R.layout.item_example, parent, false);
    }

    View view1 = exampleView.findViewById(R.id.v_first);
    View view2 = exampleView.findViewById(R.id.v_second);

    if (/* ... show view1 ? ... */) {
        view1.setVisibility(View.VISIBLE);
        view2.setVisibility(View.GONE);
    } else {
        view2.setVisibility(View.VISIBLE);
        view1.setVisibility(View.GONE);
    }
    return exampleView;
}
0
source

Source: https://habr.com/ru/post/1622816/


All Articles