0

Ich habe einen ListView mit einem Adapter erstellt, aber das einzige Problem ist, dass wir verschiedene Layouts verwenden, weil es eine Messaging-App ist. Ich möchte die Leistung mithilfe der Ansichtsrecycling verbessern, kann aber nicht herausfinden, wie die Ansicht wiederverwendet werden soll.Listview recycling bei Verwendung verschiedener Layouts

Ist es möglich, eine Ansicht Layout zu ändern oder ist es möglich:

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     MessageLog message = this.mData.get(position); 

     MessageRowViewHolder holder = new MessageRowViewHolder(); 
     int type = getItemViewType(position); 

     switch (type) { 
      case TYPE_ITEM: 

       // Inflate the correct view depending on whether the message is a reply or 
       // own message. 
       if (message.isReply()) { 
        convertView = mInflater.inflate(R.layout.row_prisoners_voicemail_message, parent, false); 
       } else { 
        convertView = mInflater.inflate(R.layout.row_own_voicemail_message, parent, false); 

       } 

       // The holder simply holds views for convenient access. 
       // It is nothing more than a dumb container. 
       holder.type = type; 
       holder.position = position; 

       holder.messageBackground = (RelativeLayout) convertView.findViewById(R.id.voiceMessageRectangleBackground); 

       holder.commentView  = (TextView) convertView.findViewById(R.id.voiceMessageCommentText); 
       holder.messageDurationView = (TextView) convertView.findViewById(R.id.voiceMessageDurationText); 
       holder.metaTextView  = (TextView) convertView.findViewById(R.id.voiceMessageMetaText); 
       holder.timestampView  = (TextView) convertView.findViewById(R.id.voiceMessageTimestampText); 

       holder.editButtonView  = (ImageView) convertView.findViewById(R.id.voiceMessageEditButtonImage); 
       holder.favouritedImageView = (ImageView) convertView.findViewById(R.id.voiceMessageFavouritedImage); 
       holder.playPauseImageView = (ImageView) convertView.findViewById(R.id.voiceMessagePlayPauseImage); 

       // Numeric tags to detect which view has been clicked. 
       holder.editButtonView.setTag(position+""); 
       holder.metaTextView.setTag(position+""); 

       holder.editButtonView.setOnClickListener(this); 
       holder.metaTextView.setOnClickListener(this); 
       break; 
      case TYPE_SEPARATOR: 
       convertView = mInflater.inflate(R.layout.grid_date_row, parent, false); 

       holder.type = type; 
       holder.dateView = (TextView) convertView.findViewById(R.id.date); 

       break; 
      case TYPE_FILLER: 
       convertView = mInflater.inflate(R.layout.grid_filler_row, parent, false); 
       holder.type = type; 
       holder.dateView = (TextView) convertView.findViewById(R.id.refreshText); 

       break; 
      case TYPE_ITEM_UPLOAD: 
       convertView = mInflater.inflate(R.layout.row_upload_voicemail_message, parent, false); 

       holder.type = type; 
       holder.messageBackground = (RelativeLayout) convertView.findViewById(R.id.voiceMessageRectangleBackground); 
       break; 
     } 

     // Short-hand notations for the resources and the message date. 
     Resources r = context.getResources(); 
     Date messageDate = message.getDate(); 

     switch (holder.type) { 
      case TYPE_ITEM: 

       // Set the duration of the call and the timestamp. 
       holder.messageDurationView.setText(PvmUtils.formatMessageDuration(context, message.getDuration())); 
       holder.timestampView.setText(PvmUtils.formatMessageTimestamp(messageDate)); 


       // Set the on click listener for editing. 


       // Show/hide the favourited view and comment. 
       if (message.isFavourited()) { 
        holder.favouritedImageView.setVisibility(View.VISIBLE); 

        String description = message.getDescription(); 
        if (description != null) { 
         holder.commentView.setVisibility(View.VISIBLE); 
         holder.commentView.setText(description); 
        } else { 
         holder.commentView.setVisibility(View.GONE); 
        } 

       } else { 
        holder.favouritedImageView.setVisibility(View.INVISIBLE); 
        holder.commentView.setVisibility(View.GONE); 
       } 


       if (message.isReply()) { 
        // If it is a reply, set the 'NEW' label if it is a new message. 
        if (message.isRead()) { 
         holder.metaTextView.setText(""); 
        } else { 
         holder.metaTextView.setText(r.getString(R.string.new_voice_message_label)); 
        } 

       } else { 
        // If it is own message, set whether the message has been uploaded and 
        // listened to; and if so, when. 

        if (message.isRead()) { 

         String dateRead = ""; 
         if (message.getReadAt() != null) { 
          dateRead = PvmUtils.formatMediumLongDate(message.getReadAt()); 
         } 

         // E.g. ✓✓ 20 Oct 17 15:54 
         String textToSet = String.format("%s %s", r.getString(R.string.doubleTick), dateRead); 
         holder.metaTextView.setText(textToSet); 
        } else { 
         holder.metaTextView.setText(r.getString(R.string.tick)); 
        } 
       } 

       break; 

      case TYPE_SEPARATOR: 

       // Just set the formatted date. 
       SimpleDateFormat formatDate = new SimpleDateFormat("dd MMM yy (EEE)", SharedResources.getLocale(context)); 
       holder.dateView.setText(formatDate.format(messageDate)); 
       break; 

      case TYPE_FILLER: 

       // Whatever this is... 
       int size = list.getHeight(); 
       holder.dateView.setPadding(0, size/2, 0, size/2); 
       break; 

      case TYPE_ITEM_UPLOAD: 

       // Set the background colour when uploading an item to yellow. 
       int colour; 
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
        colour = r.getColor(R.color.yellow_message, null); 
       } else { 
        colour = r.getColor(R.color.yellow_message); 
       } 

       holder.messageBackground.setBackgroundColor(colour); 
       break; 
     } 

     return convertView; 
    } 
+0

versuchen Sie diesen Link https://StackOverflow.com/a/44842749/1548824 – akhilesh0707

+0

Warum nicht einfach zu RecyclerView wechseln? –

+0

@DivijSehgal Welche Vorteile bietet ein RecyclerView? Wäre es einfach, von ListView zu RecyclerView zu wechseln? –

Antwort

0

Sie mehrere Layouts mit ListView verwenden können, so wandern keine Notwendigkeit, sofort zu RecyclerView ;-)

Wenn Sie‘ Re arbeitet mit einem Adapter irgendwie von BaseAdapter erstreckt, müssen Sie zwei Methoden außer Kraft setzen:

getViewTypeCount() 

Gibt die Anzahl der Ansichtenarten zurück, die von getView (int, View, ViewGroup) erstellt werden.

getItemViewType(int position) 

die Art der Ansicht erhalten, die von getView (int, Ansicht, Viewgroup) für das angegebene Element erstellt wird.

Sie einfach so viele verschiedene Ansichtstypen wie nötig definieren:

private static int VIEW_TYPE_REPLY = 0; 
private static int VIEW_TYPE_OTHER = 1; 

und dann so eine Implementierung von getItemViewType() aussehen könnte:

MessageLog message = this.mData.get(position); 
if (message.isReply()) { 
    return VIEW_TYPE_REPLY;   
} else { 
    return VIEW_TYPE_OTHER;  
} 

In getView(), ein

schreiben konnte
int viewType = getItemViewType(position); 
switch(viewType){ 
    case VIEW_TYPE_REPLY: 
     convertView = mInflater.inflate(R.layout.row_prisoners_voicemail_message, parent, false); 
     break; 
    default: 
     convertView = mInflater.inflate(R.layout.row_own_voicemail_message, parent, false); 
} 
// .... 

und später vielleicht unterschiedliche ViewHolder s verwenden, je nachdem, wie viel der Inhalt der View Typen variiert.

Durch Überschreiben der beiden Methoden aktivieren Sie das Framework, falls möglich, View s zu recyceln. Es ist also nicht notwendig zu prüfen, ob ein convertView das richtige Layout hat.

Verwandte Themen