Expandable list view with HorizontalScroll View for child view

Deadly 提交于 2021-02-11 12:04:53

问题


I'm working on Expandable ListView and used this tutorial.

https://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/

But what I'm looking for is that I want a child view with horizontal scroll view. I have an image and a text view inside for my child view. It is working vertically but I want it to work as horizontally. I've seen some other tutorials but none of them works. Can anyone tell me how can I make it work horizontally?

child_view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/textFieldBackgroundColor"
android:orientation="vertical">

<ImageView
    android:id="@+id/imageViewChild"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:layout_gravity="center"
    android:layout_marginTop="10dp" />

<TextView
    android:id="@+id/tvChildName"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="15dp"
    android:fontFamily="@font/uber_move_text_regular"
    android:gravity="center"
    android:textAlignment="center"
    android:textColor="@color/alternateTextColor"
    android:textSize="19sp" />


</LinearLayout>

adapter_view:

 private Context _context;
    private List<String> _listDataHeader; // header titles
    // child data in format of header title, child title
    private HashMap<String, List<String>> _listDataChild;

    public ExListAdapter(Context context, List<String> listDataHeader,
                         HashMap<String, List<String>> listChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;
    }

    @Override
    public Object getChild(int groupPosition, int childPosititon) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .get(childPosititon);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, final int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {

        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.categories_list_child, null);
        }

        TextView txtListChild = convertView
                .findViewById(R.id.tvChildName);

        ImageView imageViewChild = convertView.findViewById(R.id.imageViewChild);

      
        txtListChild.setText(childText);
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this._listDataHeader.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return this._listDataHeader.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.categories_list_header, null);
        }

        TextView lblListHeader = convertView
                .findViewById(R.id.tvHeader);

        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);

        ImageView headerImage = convertView.findViewById(R.id.imageViewCatHeader);
      

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

回答1:


To have children view in horizontal instead of vertical then what I found from a solution is that we can return a recycler view instead of our own views and then to return our own views we can set that data to a recycler view using adapter just like we always do. Below is adapter code to help:

Expendable List View Adapter:

public class ExListAdapter implements ExpandableListAdapter {

private Context context;
private List<categoriesModel> listModel;

public ExListAdapter(Context context, List<categoriesModel> brands) {
    this.context = context;
    this.listModel = brands;
}

@Override
public void registerDataSetObserver(DataSetObserver observer) {
}

@Override
public void unregisterDataSetObserver(DataSetObserver observer) {

}

@Override
public int getGroupCount() {
    return listModel.size();
}

@Override
public int getChildrenCount(int groupPosition) {

 // you need to return 1 here instead of length of child views as our only view is recycler view
   

return 1;
}

@Override
public Object getGroup(int groupPosition) {
    return listModel.get(groupPosition);
}

@Override
public Object getChild(int groupPosition, int childPosition) {
    return listModel.get(groupPosition);
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public boolean hasStableIds() {
    return true;
}

@SuppressLint("InflateParams")
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

    ParentHolder parentHolder = null;

    categoriesModel model = (categoriesModel) getGroup(groupPosition);

    if (convertView == null) {
        LayoutInflater userInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = userInflater.inflate(R.layout.categories_list_header, null);
        convertView.setHorizontalScrollBarEnabled(true);

        parentHolder = new ParentHolder();
        convertView.setTag(parentHolder);

    } else {
        parentHolder = (ParentHolder) convertView.getTag();
    }

    parentHolder.tvHeader = convertView.findViewById(R.id.tvHeader);
    parentHolder.tvHeader.setText(model.getName());

    parentHolder.imageView = convertView.findViewById(R.id.imageViewCatHeader);

    if (model.getCategoryImageURL() != null) {
        //model.getBaseURL() + "/" +
        Picasso.with(context).load(model.getCategoryImageURL()).into(parentHolder.imageView);
    }


    return convertView;
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

    ChildHolder childHolder = null;
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.item_group_child, parent, false);
        childHolder = new ChildHolder();
        convertView.setTag(childHolder);
    } else {
        childHolder = (ChildHolder) convertView.getTag();
    }


   //here we are setting up child view with a recycler view.

    ChildHolder.horizontalListView = convertView.findViewById(R.id.childRecyclerView);
    LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
    ChildHolder.horizontalListView.setLayoutManager(layoutManager);


    ChildAdapter horizontalListAdapter = new ChildAdapter(context, listModel.get(groupPosition).getChildModel());
    ChildHolder.horizontalListView.setAdapter(horizontalListAdapter);

    return convertView;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return false;
}

@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEmpty() {
    return false;
}

@Override
public void onGroupExpanded(int groupPosition) {

}

@Override
public void onGroupCollapsed(int groupPosition) {

}

@Override
public long getCombinedChildId(long groupId, long childId) {
    return 0;
}

@Override
public long getCombinedGroupId(long groupId) {
    return 0;
}

private static class ChildHolder {
    static RecyclerView horizontalListView;
}

private static class ParentHolder {
    TextView tvHeader;
    ImageView imageView;
}

}

Now the child adapter we need to set up data for the recycler view data is below:\

 public class ChildAdapter extends RecyclerView.Adapter<ChildAdapter.ViewHolder> 
 {

private Context context;
private List<subCategoriesModel> subCategoriesModelList;
private final static String TAG = "childAdapterClass";

public ChildAdapter(Context context, List<subCategoriesModel> mobiles) {
    this.context = context;
    this.subCategoriesModelList = mobiles;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View cardView = inflater.inflate(R.layout.categories_list_child, null, false);
    ViewHolder viewHolder = new ViewHolder(cardView);
    viewHolder.imageViewChild = cardView.findViewById(R.id.imageViewChild);
    viewHolder.tvChildName = cardView.findViewById(R.id.tvChildName);
    return viewHolder;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    ImageView imageView = holder.imageViewChild;

    if (subCategoriesModelList.get(position).getImageURL() != null) {
        //subCategoriesModelList.get(position).getBaseURL() + "/" +
        Picasso.with(context).load(subCategoriesModelList.get(position).getImageURL()).into(imageView);
    }

    TextView tvName = holder.tvChildName;
    tvName.setText(subCategoriesModelList.get(position).getName());

    LinearLayout layout = holder.linearLayout;

    layout.setOnClickListener(v -> {
       /* Bundle bundle = new Bundle();
        bundle.putString("subCatId", subCategoriesModelList.get(position).getId());
        Fragment fragment = new GetCategoriesFragment();
        fragment.setArguments(bundle);
        ((FragmentActivity) context).getSupportFragmentManager().beginTransaction()
                .replace(R.id.content_frame, fragment)
                .addToBackStack(null)
                .commit();
        Log.d(TAG, "adapter:"+subCategoriesModelList.get(position).getId());*/
    });




}

@Override
public int getItemCount() {
    return subCategoriesModelList.size();
}

@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    ImageView imageViewChild;
    TextView tvChildName;
    LinearLayout linearLayout;

    public ViewHolder(View itemView) {
        super(itemView);
        imageViewChild = itemView.findViewById(R.id.imageViewChild);
        tvChildName = itemView.findViewById(R.id.tvChildName);
        linearLayout = itemView.findViewById(R.id.linearLayout);
    }
}

}

Now to send the data from Main Class you need to create a model for parent with the array list of child.. Like a Category has 3 sub categories now all the sub categories will be added into an array list and that arraylist will be added with the model of parent child...

Ex:

Model m = new Model(categoryID,categoryName,ArrayList<subCategory> model)


来源:https://stackoverflow.com/questions/63046952/expandable-list-view-with-horizontalscroll-view-for-child-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!