两个ArrayList一个RecyclerView适配器

时间:2017-02-25 00:27:13

标签: java android arraylist android-recyclerview

我有一个聊天屏幕,我可以与其他用户聊天,我将聊天数据(消息,时间和发件人通过列表)发送到RecyclerAdapter,它使用data填充聊天视图。现在我还有一个列表,其中包含不同的数据布局。喜欢这个

Demo Screen

这是我的方法,我将第二个arraylist称为RecyclerAdapter

public void TransferResultTo_Activity(List<Image_data_Wrapper> list) {
        Log.d(TAG,"Here is data Result From AsyncTask "+list.size());
        getResult=list;
        Image_data_Wrapper Image=getResult.get(0);
        Log.d(TAG,"Result from Image data "+Image.getPage_Title());
        adapter=new Chat_Adapter(this,message,getResult);
        adapter.notifyDataSetChanged();
    }

如上所述,当我尝试通过recyclerView.setAdapter(adapter);调用适配器时,它会从屏幕中删除所有消息并显示我的图像数据。但我希望保留所有消息并通过新列表显示带有数据的图像

这是我的聊天适配器

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

    private String UserID;
    private Context context;
    //TAG FOR TRACKING SELF MESSAGE
    private int Self_Msg=0;
    //ARRAYLIST OF MESSAGES OBJECT CONTAINING ALL THE MESSAGES IN THE THREAD
    private List<Chat_Wrapper> arrayList_message;
    public static final String TAG="###CHAT_ADAPTER###";
    private List<Image_data_Wrapper> data_Result;
    boolean valtype;


    public Chat_Adapter(Context context, List<Chat_Wrapper> message) {
        //UserID = userID;
        this.context = context;
        this.arrayList_message = message;
        Log.d(TAG,"Chat Adapter Calling");
    }
    public Chat_Adapter(Context context, List<Image_data_Wrapper> result,boolean val) {
        this.context = context;
        this.data_Result = result;
        this.valtype=val;
        Log.d(TAG,"Image data Chat Adapter Calling");
    }

    public Chat_Adapter() {
    }


    @Override
    public Chat_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView;
        Log.d(TAG,"On Create View Holder Calling ");
        if (viewType==Self_Msg){
            itemView= LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item,parent,false);
            Log.d(TAG,"On Create View Holder Calling View Type is "+itemView);
        }

        else if (valtype==true){
            itemView= LayoutInflater.from(parent.getContext()).inflate(R.layout.Image_data_layout,parent,false);
            Log.d(TAG,"ON CREATE VIEW HOLDER RUNNING AND data RESULT VIEW TYPE IS RUNNING "+viewType);
        }

        else {
            itemView= LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item,parent,false);
            Log.d(TAG,"On Create View Holder Calling View Type is "+itemView);
        }
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(Chat_Adapter.ViewHolder holder, int position) {
        if (valtype==true){
            Image_data_Wrapper wrapper=data_Result.get(position);
            holder.data_title.setText(wrapper.getPage_Title());
            holder.data_link.setText(wrapper.getPage_Link());
            holder.data_snippet.setText(wrapper.getPage_Desc());
            Picasso.with(context).load(wrapper.getPage_ImageThumb()).into(holder.Image_Image);
            valtype=false;

        }
        else {

            Log.d(TAG,"On Bind VIew Holder Context "+context);
            Chat_Wrapper wrapper=arrayList_message.get(position);
            Log.d(TAG,"On Bind VIew Holder Chat Wrapper "+wrapper);
            holder.Message.setText(wrapper.getMessage());
            holder.TimeStamp.setText(wrapper.getTimestamp());

        }



    }

    @Override
    public int getItemCount() {
        Log.d(TAG,"Get Item Count Running");
        int items;
        if (valtype==true){
            Log.d(TAG,"data Result Array is not empty");
            items=data_Result.size();
            Log.d(TAG,"Total Number Of Item "+items);
            return items;
        }
        else {
            Log.d(TAG,"ARRAY SIZE AT GETITEM COUNT "+arrayList_message.size());
            return arrayList_message.size();
        }





    }


    @Override
    public int getItemViewType(int position) {
        Log.d(TAG,"Get Item View Type Running");
        return position;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView Message,TimeStamp,data_title,data_link,data_snippet;
        ImageView User_image,Image_Image;
        ImageButton data_SendButton;


         public ViewHolder(View itemView) {
             super(itemView);
             Message= (TextView) itemView.findViewById(R.id.Single_Item_Chat_Message);
             TimeStamp= (TextView) itemView.findViewById(R.id.Single_Item_Chat_TimeStamp);
             User_image= (ImageView) itemView.findViewById(R.id.Single_Item_Chat_ImageView);

             if (valtype==true){
                 Log.d(TAG,"Setting View For Image data ");
                 data_title= (TextView) itemView.findViewById(R.id.Image_data_Title);
                 data_link= (TextView) itemView.findViewById(R.id.Image_data_Link);
                 data_snippet= (TextView) itemView.findViewById(R.id.Image_data_Snippet);

                 Image_Image= (ImageView) itemView.findViewById(R.id.Image_data_Image);
                 data_SendButton= (ImageButton) itemView.findViewById(R.id.Image_data_SendButton);
             }




        }
    }

    public void updateDataWithdataResult(List<Image_data_Wrapper> list,boolean setValue){
        Log.d(TAG,"Update Data Method Calling");
        this.data_Result=list;
        this.valtype=setValue;
    }
}

我对此代码所面临的问题

  • 使用notifiydatasetchanged只有Adapter构造函数调用(更正)但从不 getItemCount()
  • 发送带有数据的布尔值是否正确检查,如果只是来自ImageArrayList的调用,则输入其相关数据或视图?
  • 使用自己的布局将两个List放入单个RecyclerView的最佳方法是什么

更新:当我通过recyclerView.setAdapter(adapter)调用适配器时,它按我的意愿工作,但adapter.notifyDataSetChanged使调用卡在适配器构造函数中停止(感谢DanielLaneDC)。那么我可以这样或adapter.notifyDataSetChanged应该工作吗?

4 个答案:

答案 0 :(得分:15)

听起来您想要使用相同的RecyclerView.Adapter在同一个RecyclerView中显示两个不同的项目列表。值得庆幸的是,这是RecyclerView.Adapter可以很好地处理的事情。

以下是RecyclerView.Adapter的外观:

Activity

以下是您List<ChatWrapper> messages; List<ImageDataWrapper> images; ChatAdapter adapter; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); messages = new ArrayList<>(); images = new ArrayList<>(); ChatAdapter adapter = new ChatAdapter(this, messages, images); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } public void addMessage(ChatWrapper message){ messages.add(message); adapter.notifyDataSetChanged(); } public void removeMessage(ChatWrapper message){ if(messages.remove(message)){ adapter.notifyDataSetChanged(); } } public void addImage(ImageDataWrapper image){ images.add(image); adapter.notifyDataSetChanged(); } public void removeImage(ImageDataWrapper image){ if(images.remove(image)){ adapter.notifyDataSetChanged(); } } 需要的内容:

addMessage(ChatWrapper)

如果您想更新数据,只需针对消息调用removeMessage(ChatWrapper)addImage(ImageDataWrapper),针对图片调用removeImage(ImageDataWrapper)valType

一些关键点:

  • 您不想创建任何新的适配器或列表,只需要在现有对象上调用方法。
  • 您的适配器应该像处理消息和图像一样,但只是它可以处理0条消息或0图像(没有getItemCount()变量,luac -l -l应始终返回大小两个列表合并等。)

答案 1 :(得分:1)

首先你需要在单个arraylist中组合两个数组,比如.. firsArrlist.addAll(secondArrList);

并传入recyclerview适配器并使用某个标志进行迁移,并使用另一个查看器获取特定标志,以在recyclerview中设置该视图。

总计数必须是firstArrlist.size + secondArrList.size

答案 2 :(得分:0)

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
    ...
    public ViewHolder0(View itemView){
    ...
    }
}

class ViewHolder2 extends RecyclerView.ViewHolder {
    ...
    public ViewHolder2(View itemView){
    ...
}

@Override
public int getItemViewType(int position) {
    // Just as an example, return 0 or 2 depending on position
    // Note that unlike in ListView adapters, types don't have to be contiguous
    return position % 2 * 2;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     switch (viewType) {
         case 0: return new ViewHolder0(...);
         case 2: return new ViewHolder2(...);
         ...
     }
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    switch (holder.getItemViewType()) {
        case 0:
            ViewHolder0 viewHolder0 = (ViewHolder0)holder;
            ...
            break;

        case 2:
            ViewHolder2 viewHolder2 = (ViewHolder2)holder;
            ...
            break;
    }
}

}

答案 3 :(得分:0)

我也遇到了同样的问题。 您可以根据需要创建Pojo类,然后输入关联,例如,一个聊天可以包含多个图像。然后构建聊天对象并在其中插入图像列表。 在将列表传递给适配器之前,请使用原始数据填充它。 我知道这可能不是您需要的好解决方案,但是 请记住,您可以完全控制,而无需细分列表。