Java 如何根据类别使用节标题实现RecyclerView?

Java 如何根据类别使用节标题实现RecyclerView?,java,android,header,android-recyclerview,sections,Java,Android,Header,Android Recyclerview,Sections,我想实现列表中的部分。我有一份任务清单。列表有一个自定义适配器,它扩展了recyclerview滑动适配器,因为我已经实现了对recyclerview的滑动手势 现在,任务列表与已完成和挂起的任务一起显示。每个列表项都有一个复选框,显示任务已完成或挂起 若复选框被选中,则任务完成,反之亦然。现在我想在这个标题中做两个部分。一个用于已完成的任务,另一个用于挂起的任务 所以完成的任务应该显示在完成的部分中,反之亦然。此外,如果未选中任务,即挂起,并且如果用户选中该复选框,则该项应从挂起部分删除,并应

我想实现列表中的部分。我有一份任务清单。列表有一个自定义适配器,它扩展了recyclerview滑动适配器,因为我已经实现了对recyclerview的滑动手势

现在,任务列表与已完成和挂起的任务一起显示。每个列表项都有一个复选框,显示任务已完成或挂起

若复选框被选中,则任务完成,反之亦然。现在我想在这个标题中做两个部分。一个用于已完成的任务,另一个用于挂起的任务

所以完成的任务应该显示在完成的部分中,反之亦然。此外,如果未选中任务,即挂起,并且如果用户选中该复选框,则该项应从挂起部分删除,并应添加到已完成部分,反之亦然

我向一家图书馆查询了一些章节

但当我尝试实现该库时,我得到了一个错误,即适配器不能扩展两个类,因为我以前扩展过recyclerview swipe库

适配器:

    public class IAdapter extends RecyclerSwipeAdapter<IAdapter.ItemViewHolder> {

    public ArrayList<Task> items;
    Context conext;
    public int _mId;

    List<Task> itemsPendingRemoval = new ArrayList<>();

    public IAdapter(Context context, ArrayList<Task> item) {
        this.conext=context;
       this.items=item;
    }


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

    }

    public static class ItemViewHolder extends RecyclerView.ViewHolder {
        Task task;
        CheckBox cb;
        SwipeLayout swipeLayout;
        TaskTableHelper taskTableHelper;
        ItemViewHolder(final View itemView) {
            super(itemView);

            taskTableHelper= new TaskTableHelper(itemView.getContext());
            swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe);
            cb = (CheckBox) itemView.findViewById(R.id.checkbox);

        }
    }

    @Override
    public void onBindViewHolder(final ItemViewHolder itemViewHolder,final int i) {

        itemViewHolder.cb.setText(items.get(i).getTitle());

        itemViewHolder.task = items.get(i);

        int taskId = itemViewHolder.task.getId();

        itemViewHolder.task = itemViewHolder.taskTableHelper.getTask(taskId);

        int status = itemViewHolder.task.getStatus();

        if(status == 0)
        {
            itemViewHolder.cb.setTextColor(Color.WHITE);
        }

        else {

            itemViewHolder.cb.setChecked(true);

            itemViewHolder.cb.setTextColor(Color.parseColor("#B0BEC5"));

        }


       itemViewHolder.cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (isChecked) {

                    itemViewHolder.cb.setTextColor(Color.parseColor("#B0BEC5"));

                    itemViewHolder.task.setStatus(1);

                    itemViewHolder.taskTableHelper.updateStatus(itemViewHolder.task);

                }
                else

                {

                    itemViewHolder.cb.setTextColor(Color.WHITE);

                    itemViewHolder.task.setStatus(0);

                    itemViewHolder.taskTableHelper.updateStatus(itemViewHolder.task);

                }

            }

        });



        final Task item = items.get(i);
        itemViewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right,itemViewHolder.swipeLayout.findViewById(R.id.bottom_wrapper_2));
        itemViewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);

        itemViewHolder.swipeLayout.setOnDoubleClickListener(new SwipeLayout.DoubleClickListener() {
            @Override
            public void onDoubleClick(SwipeLayout layout, boolean surface) {
                Toast.makeText(conext, "DoubleClick", Toast.LENGTH_SHORT).show();
            }
        });
        itemViewHolder.swipeLayout.findViewById(R.id.trash2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mItemManger.removeShownLayouts(itemViewHolder.swipeLayout);
                items.remove(i);
                notifyItemRemoved(i);
                notifyItemRangeChanged(i, items.size());
                mItemManger.closeAllItems();

                itemViewHolder.taskTableHelper.deleteTask(item);

                _mId = item.getAlertId();

                cancelNotification();

                Toast.makeText(view.getContext(), "Deleted " + itemViewHolder.cb.getText().toString() + "!", Toast.LENGTH_SHORT).show();
            }
        });

        itemViewHolder.swipeLayout.findViewById(R.id.done).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                itemViewHolder.task.setStatus(1);
                itemViewHolder.taskTableHelper.updateStatus(itemViewHolder.task);
                itemViewHolder.cb.setChecked(true);
                Toast.makeText(conext, "Task Completed.", Toast.LENGTH_SHORT).show();
            }
        });

        itemViewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                boolean mEditMode;

                int id = item.getId();
                int priority = item.getTaskPriority();
                String title = item.getTitle();
                String alertDate = item.getAlertDate();
                String alertTime = item.getAlertTime();
                String dueDate = item.getDueDate();
                String dueTime = item.getDueTime();
                _mId = item.getAlertId();

                int listId = item.getList();

                mEditMode = true;

                Intent i = new Intent(conext, AddTaskActivity.class);

                i.putExtra("taskId", id);
                i.putExtra("taskTitle", title);
                i.putExtra("taskPriority", priority);
                i.putExtra("taskAlertTime", alertTime);
                i.putExtra("taskAlertDate", alertDate);
                i.putExtra("taskDueDate", dueDate);
                i.putExtra("taskDueTime", dueTime);
                i.putExtra("taskListId", listId);
                i.putExtra("EditMode", mEditMode);
                i.putExtra("AlertId",_mId);

                conext.startActivity(i);

            }
        });


        mItemManger.bindView(itemViewHolder.itemView, i);

    }

    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup,int position) {

            View itemView = LayoutInflater.
                    from(viewGroup.getContext()).
                    inflate(R.layout.card_layout, viewGroup, false);
            return new ItemViewHolder(itemView);

    }



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


    public void remove(int position) {
       Task item = items.get(position);
        if (itemsPendingRemoval.contains(item)) {
            itemsPendingRemoval.remove(item);
        }
        if (items.contains(item)) {
            items.remove(position);
            notifyItemRemoved(position);
        }
    }

    public void cancelNotification()
    {
        AlarmManager alarmManager = (AlarmManager)conext.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(conext, NotificationReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(conext,_mId, intent, 0);
        alarmManager.cancel(pendingIntent);
    }
    @Override
    public int getSwipeLayoutResourceId(int position) {
        return R.id.swipe;
    }
}
我该怎么做?有人能帮忙吗


谢谢你。

你可以通过硬编码自己完成。有很多聪明的方法可以做到这一点。请点击以下链接。然后给你选一个


您可以通过“sectioned recyclerViews android库”来搜索更多内容。

您可以使用我在本文中解释的库来实现它


为了实现SwipeLayout,不要扩展RecyclerSwipeAdapter,扩展SectionedRecycleServiceAdapter并在ItemViewHolder/onBindItemViewHolder中实现SwipeLayout,就像您所做的那样。

将回收器视图拆分为多个部分的最简单方法是使用一个布局,其中标题和项目已经就位,然后如果标题相同,则更改可见性

布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tvHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="start"
        android:padding="16dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/primary"
        android:textStyle="bold"
        tools:text="A" />

    <TextView
        android:id="@+id/tvName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvHeader"
        android:background="?android:attr/selectableItemBackground"
        android:padding="16dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        tools:text="Adam" />

</RelativeLayout>

适配器(2018 Kotlin版):

class ContactAdapter@injectconstructor():RecyclerView.Adapter(){
变量onItemClick:((触点)->单位)?=null
var contacts=emptyList()
重写getItemCount():Int{
返回联系人。大小
}
override onCreateViewHolder(父级:ViewGroup,viewType:Int):ViewHolder{
返回ViewHolder(LayoutFlater.from(parent.context)。充气(R.layout.item_contact,parent,false))
}
覆盖BindViewHolder(holder:ViewHolder,位置:Int){
val name=联系人[位置].name
holder.header.text=name.substring(0,1)
holder.name.text=名称
//如果不是第一个项目,请检查上面的项目是否具有相同的标题
if(位置>0&&contacts[position-1].name.substring(0,1)==name.substring(0,1)){
holder.headerTextView.visibility=View.GONE
}否则{
holder.headerTextView.visibility=视图.VISIBLE
}
}
内部类ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
val headerTextView:TextView=itemView.tvHeader
val-nameTextView:TextView=itemView.tvName
初始化{
itemView.setOnClickListener{
onItemClick?.invoke(联系人[适配器位置])
}
}
}
}


也可能有帮助:



旧Java适配器版本:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.DataViewHolder> {

    private List<Contact> mData;

    @Inject
    public RecyclerAdapter() {
        mData = new ArrayList<>();
    }

    public void setData(List<Contact> data) {
        mData = data;
    }

    public Contact getItem(int position){
        return mData.get(position);
    }

    @Override
    public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_contact, parent, false);
        return new DataViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final DataViewHolder holder, int position) {
        Contact contact = mData.get(position);
        holder.headerTextView.setText(contact.getName().substring(0, 1));
        holder.nameTextView.setText(contact.getName());

        // if not first item check if item above has the same header
        if (position > 0 && mData.get(position - 1).getName().substring(0, 1).equals(contact.getName().substring(0, 1))) {
            holder.headerTextView.setVisibility(View.GONE);
        } else {
            holder.headerTextView.setVisibility(View.VISIBLE);
        }
    }

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

    public class DataViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.text_header)
        TextView headerTextView;
        @BindView(R.id.text_name)
        TextView nameTextView;

        public DataViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}
公共类RecyclerAdapter扩展了RecyclerView.Adapter{ 私有列表数据; @注入 公共回收设备适配器(){ mData=newarraylist(); } 公共无效设置数据(列表数据){ mData=数据; } 公共联系人getItem(内部位置){ 返回mData.get(位置); } @凌驾 public DataViewHolder onCreateViewHolder(视图组父级,int-viewType){ View itemView=LayoutFlater.from(parent.getContext())。充气(R.layout.item_contact,parent,false); 返回新的DataViewHolder(itemView); } @凌驾 公共无效onBindViewHolder(最终数据视图持有人,内部位置){ Contact Contact=mData.get(位置); holder.headerTextView.setText(contact.getName().substring(0,1)); holder.nameTextView.setText(contact.getName()); //如果不是第一个项目,请检查上面的项目是否具有相同的标题 if(position>0&&mData.get(position-1).getName().substring(0,1).equals(contact.getName().substring(0,1))){ holder.headerTextView.setVisibility(View.GONE); }否则{ holder.headerTextView.setVisibility(视图.可见); } } @凌驾 public int getItemCount(){ 返回mData.size(); } 公共类DataViewHolder扩展了RecyclerView.ViewHolder{ @BindView(R.id.text\u标题) 文本视图标题文本视图; @BindView(R.id.text\u名称) TextView名称TextView; 公共数据视图持有者(视图项视图){ 超级(项目视图); ButterKnife.bind(这个,itemView); } } }
查看Github上的my library,它可用于轻松创建节:

mRecylerView.setLayoutManager(…);
/*创建适配器*/
RecyclerAdapter baseAdapter=新的RecyclerAdapter(…);
/*创建分段适配器。适配器类型可以是RecyclerView.Adapter*/
SectionedAdapter=新的SectionedAdapter(SectionViewHolder.class,baseAdapter);
/*添加您的分区*/
节适配器。添加节(0/*位置*/,“标题节1”);
/*将适配器连接到RecyclerView*/
mRecylerView.setAdapter(sectionAdapter);

希望有帮助。

是的,我已经浏览了这些链接。但是我可以用recyclerview滑动库扩展这个库吗?当我尝试实现其中一个时,我得到一个错误,即类不能扩展多个类@vabhi vabI收到一个错误,因为当我尝试扩展SectionedRecyclServiceView适配器时,适配器必须实现方法onBindViewHolder(VH,int)。我正在更新BindViewHolder方法,请检查@vabhi VABHO如何在上述方法中使用此行“miteManger.bindView(itemViewHolder.itemView,i)”
class ContactAdapter @Inject constructor() : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {

    var onItemClick: ((Contact) -> Unit)? = null
    var contacts = emptyList<Contact>()

    override fun getItemCount(): Int {
        return contacts.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_contact, parent, false))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val name = contacts[position].name
        holder.header.text = name.substring(0, 1)
        holder.name.text = name

        // if not first item, check if item above has the same header
        if (position > 0 && contacts[position - 1].name.substring(0, 1) == name.substring(0, 1)) {
            holder.headerTextView.visibility = View.GONE
        } else {
            holder.headerTextView.visibility = View.VISIBLE
        }
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val headerTextView: TextView = itemView.tvHeader
        val nameTextView: TextView = itemView.tvName

        init {
            itemView.setOnClickListener {
                onItemClick?.invoke(contacts[adapterPosition])
            }
        }
    }
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.DataViewHolder> {

    private List<Contact> mData;

    @Inject
    public RecyclerAdapter() {
        mData = new ArrayList<>();
    }

    public void setData(List<Contact> data) {
        mData = data;
    }

    public Contact getItem(int position){
        return mData.get(position);
    }

    @Override
    public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_contact, parent, false);
        return new DataViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final DataViewHolder holder, int position) {
        Contact contact = mData.get(position);
        holder.headerTextView.setText(contact.getName().substring(0, 1));
        holder.nameTextView.setText(contact.getName());

        // if not first item check if item above has the same header
        if (position > 0 && mData.get(position - 1).getName().substring(0, 1).equals(contact.getName().substring(0, 1))) {
            holder.headerTextView.setVisibility(View.GONE);
        } else {
            holder.headerTextView.setVisibility(View.VISIBLE);
        }
    }

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

    public class DataViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.text_header)
        TextView headerTextView;
        @BindView(R.id.text_name)
        TextView nameTextView;

        public DataViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}
mRecylerView.setLayoutManager(...);
/*create Adapter*/
RecyclerAdapter<Customer> baseAdapter = new RecyclerAdapter<>(...);
/*create sectioned adapter. the Adapter type can be RecyclerView.Adapter*/
SectionedAdapter<String, RecyclerAdapter> adapter = new SectionedAdapter<>(SectionViewHolder.class, baseAdapter);
/*add your sections*/
sectionAdapter.addSection(0/*position*/, "Title Section 1");
/*attach Adapter to RecyclerView*/
mRecylerView.setAdapter(sectionAdapter);