Tengo una pantalla de chat donde puedo chatear con otros usuarios, yo soy el envío de chat de datos (mensaje,el tiempo y el emisor a través de la Lista) para RecyclerAdapter que pueblan el chat de puntos de vista con los datos.Ahora tengo uno más de la Lista que tiene los datos con diseño diferente. Como este

Dos ArrayList uno RecyclerView Adaptador

Aquí es mi método desde donde yo estoy llamando segundo arraylist en 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();
    }

Como en el método anterior, cuando intento llamar adaptador recyclerView.setAdapter(adapter); es eliminar todos los mensajes de la pantalla y muestra los datos de mi imagen. pero quiero mantener todos los mensajes y mostrar la imagen con los datos a través de la nueva lista

Aquí está mi Chat Adaptador de

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;
}
}

Los problemas que me estoy enfrentando con este código

  • Con notifiydatasetchanged sólo el Adaptador constructor está llamando(Correcta), pero nunca getItemCount()
  • Está enviando el valor booleano con los datos es la manera correcta de comprobar, Si las llamadas de ImageArrayList sólo, a continuación, entrar en sus datos o puntos de vista?
  • ¿Cuál es la mejor manera para obtener la Lista en una sola RecyclerView con su propio diseño

ACTUALIZACIÓN : Cuando llamo adaptador recyclerView.setAdapter(adapter) funcionó como yo quiero, sino como adapter.notifyDataSetChanged hacen llamar atrapado en el adaptador del constructor (Gracias a DanielLaneDC). Así puedo dejarlo así o adapter.notifyDataSetChanged debería funcionar?

  • ¿Estaría en lo correcto en decir que, en el fondo, sólo quiero ser capaz de mostrar dos listas de elementos en una sola RecyclerView, manejado por una sola RecyclerView.Adaptador?
  • sí, tiene usted derecho
InformationsquelleAutor androidXP | 2017-02-25

4 Comentarios

  1. 15

    Parece que quieres mostrar dos listas diferentes de los elementos en la misma RecyclerView utilizando el mismo RecyclerView.El adaptador. Afortunadamente, este es el tipo de cosa RecyclerView.Adaptador puede manejar muy bien.

    He aquí cómo su RecyclerView.El adaptador debe buscar:

    public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    final int VIEW_TYPE_MESSAGE = 0;
    final int VIEW_TYPE_IMAGE = 1;
    Context context;
    List<ChatWrapper> messages;
    List<ImageDataWrapper> images;
    public ChatAdapter(Context context, List<ChatWrapper> messages, List<ImageDataWrapper> images){
    this.context = context;
    this.messages = messages;
    this.images = images;
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
    if(viewType == VIEW_TYPE_MESSAGE){
    return new MessageViewHolder(itemView);
    }
    if(viewType == VIEW_TYPE_IMAGE){
    return new ImageViewHolder(itemView);
    }
    return null;
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position){
    if(viewHolder instanceof MessageViewHolder){
    ((MessageViewHolder) viewHolder).populate(messages.get(position));
    }
    if(viewHolder instanceof ImageViewHolder){
    ((ImageViewHolder) viewHolder).populate(images.get(position - messages.size()));
    }
    }
    @Override
    public int getItemCount(){
    return messages.size() + images.size();
    }
    @Override
    public int getItemViewType(int position){
    if(position < messages.size()){
    return VIEW_TYPE_MESSAGE;
    }
    if(position - messages.size() < images.size()){
    return VIEW_TYPE_IMAGE;
    }
    return -1;
    }
    public class MessageViewHolder extends RecyclerView.ViewHolder {
    TextView message;
    TextView timeStamp;
    ImageView userImage;
    public MessageViewHolder(View itemView){
    super(itemView);
    message = (TextView) itemView.findViewById(R.id.Single_Item_Chat_Message);
    timeStamp = (TextView) itemView.findViewById(R.id.Single_Item_Chat_TimeStamp);
    userImage = (ImageView) itemView.findViewById(R.id.Single_Item_Chat_ImageView);
    }
    public void populate(ChatWrapper chatWrapper){
    message.setText(chatWrapper.getMessage());
    userImage.setText(chatWrapper.getTimestamp());
    }
    }
    public class ImageViewHolder extends RecyclerView.ViewHolder {
    TextView dataTitle;
    TextView dataLink;
    TextView dataSnippet;
    ImageView image;
    ImageButton dataSendButton;
    public ImageViewHolder(View itemView){
    super(itemView);
    dataTitle = (TextView) itemView.findViewById(R.id.Image_data_Title);
    dataLink = (TextView) itemView.findViewById(R.id.Image_data_Link);
    dataSnippet = (TextView) itemView.findViewById(R.id.Image_data_Snippet);
    image = (ImageView) itemView.findViewById(R.id.Image_data_Image);
    dataSendButton = (ImageButton) itemView.findViewById(R.id.Image_data_SendButton);
    }
    public void populate(ImageDataWrapper imageDataWrapper){
    dataTitle.setText(imageDataWrapper.getPage_Title());
    dataLink.setText(imageDataWrapper.getPage_Link());
    dataSnippet.setText(imageDataWrapper.getPage_Desc());
    Picasso.with(context).load(imageDataWrapper.getPage_ImageThumb()).into(image);
    }
    }
    }

    Lo que su Activity va a necesitar:

    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();
    }
    }

    Cuando desea actualizar los datos, sólo tiene que llamar addMessage(ChatWrapper) o removeMessage(ChatWrapper) para los mensajes y addImage(ImageDataWrapper) o removeImage(ImageDataWrapper) para las imágenes.

    Algunos puntos clave:

    • Usted no desea crear los nuevos Adaptadores o Listas, simplemente quiere llamar a métodos en nuestra objetos existentes.
    • El Adaptador debe comportarse como si siempre tiene que lidiar con los mensajes y las imágenes, pero que se puede manejar 0 mensajes o 0 imágenes (no valType variable, getItemCount() siempre debe devolver el tamaño de las listas combinadas, etc.)
    • thx voy a chk nd volver con resultado pronto
    • Todavía atrapado en el adaptador de construtor nada está llamando después de Registro y dice que el Tamaño de cada objeto arraylist Chat Adapter Calling 2 1 . Hice como usted ha mencionado, pero todavía no funciona
    • He editado mi respuesta a incluir cómo se debe crear el adaptador.
    • Como u puede ver en mi código anterior hice //adapter=new Chat_Adapter(this,list,true); sin crear ninguna nueva instancia del adaptador o de la lista. Así que he intentado esto pero no ha habido suerte por cierto gracias por ur esfuerzos.
    • Llamar new Chat_Adapter va a ser la creación de un nuevo adaptador. En su TransferResultTo_Activity método está creando un nuevo adaptador. Sólo necesita modificar la lista sin necesidad de recrear el adaptador y, a continuación, notificar el adaptador de mantener una referencia a la misma adaptador que pasa a la RecyclerView.
    • No, en realidad yo sólo era la prueba de que el tiempo, pero como dijo u yo estoy usando el código comentado adaptador en mi código de arriba
    • En su TransferResultTo_Activity método en la apertura de correos, crear un nuevo adaptador de aquí: Chat_Adapter chatAdapter=new Chat_Adapter();
    • No entiendo por qué me quedé en el constructor siempre me llama con los datos de la imagen e, incluso, como he demostrado más arriba, me estoy poniendo de su sizs 2 y 1
    • Si se agrega el resto de su código correspondiente a la pregunta, puedo editar mi respuesta para solucionar el resto de los bits que están rotos.
    • Por Favor, Revise La Actualización De La Pregunta
    • He editado mi respuesta para incluir el código necesario para el uso de agregar/quitar los mensajes y de las imágenes. Asegúrese de que usted nunca está creando más adaptadores o listas de los que tomamos en Activity.onCreate(Bundle).
    • Como puedo editar el código de arriba, yo no soy la creación de cualquier nueva instancia del adaptador o de la lista de su primo variables de clase.Voy a actualizar muy pronto después de probar su código editado.Thx
    • Mismo Problema viene de código atrapado en el Constructor. Pero no cuando me llame recyclerview.setadapter método.Pero te mereces un upvote seguro
    • Cuando usted dice «coming código atrapado en el Constructor» podría por favor explicar qué quiere decir?
    • Código atrapado en el constructor significa que cada vez que llame a notifydatasetchanged puedo ver en el Registro de constructor se ejecuta tanto con el tamaño de un array de valores y obtener el recuento de las llamadas no después de ese o de cualquier otro método.
    • ¿Qué significa «constructor se ejecuta»? El Adaptador del constructor no debe ser llamado de nuevo así que es raro que suena como él es.
    • cada vez que llame a notifydatasetchanged se muestra en el Registro que (yo hacía de Registro en el constructor Véase el código de arriba) Constructor de obtener la llamada y después de que el registro no se genera.
    • Gracias por la solución. esta es la solución perfecta para la OP del problema. debe de ser aceptado como respuesta
    • Este enfoque funcionó muy bien para mí en situación similar

  2. 1

    Primer lugar usted necesita para combinar tanto la matriz en una sola arraylist gusta..
    firsArrlist.addAll(secondArrList);

    y pasar a recyclerview adaptador y migrar con algunos bandera y tomar otro viewholder de bandera en particular para establecer que ver en recyclerview.

    Y recuento total se debe tanto firstArrlist.tamaño + secondArrList.tamaño

  3. 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;
    }
    }

    }

  4. 0

    Yo tenía tu mismo problema.
    Puede crear una clase Pojo si usted necesita y entrar en la asociación, por ejemplo, un chat puede tener varias imágenes. Luego de construir el objeto chat y insertar una lista de imágenes en ella.
    Antes de pasar a la lista para el adaptador, rellenarlo con los datos originales.
    Sé que esto puede no ser una buena solución para sus necesidades, pero
    recuerde que usted puede tener el control total, sin la segmentación de las listas.

    • va a intentar su solución. gracias

Dejar respuesta

Please enter your comment!
Please enter your name here