0

そこで、このレイアウトを使用するアイテムのカスタム リストビューを作成しました。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="5dp"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingLeft="5dp"
    android:id="@+id/llContactRow"
    android:orientation="horizontal">

    <CheckBox
        android:id="@+id/cbMultipleSelect"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:drawableRight="@android:color/transparent"
        android:clickable="false"
        android:layout_weight="0"
        />

    <com.pkmmte.view.CircularImageView
        android:id="@+id/ivContactPicture"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight="0.2"
        android:src="@drawable/user_default"
        android:paddingLeft="10dp"
        app:civ_shadow="true" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:id="@+id/llContactDetails"
        android:layout_weight="1">

        <TextView
            android:id="@+id/tvContactName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Areeb"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/tvContactNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="03342228458" />

    </LinearLayout>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="16dp"
        android:id="@+id/ivContactSelectionTick"
        android:src="@drawable/contact_selection_tick"
        android:visibility="invisible"
        android:layout_weight="0.2" />

</LinearLayout>

このリストビューのカスタム アダプターは次のとおりです。

import java.util.ArrayList;
import java.util.List;

import com.footstapps.contactshelper.ContactInfo;
import com.footstapps.letsmeet.R;
import com.pkmmte.view.CircularImageView;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ContactsListAdapter extends BaseAdapter{

    private Context context;
    private List<ContactInfo> contacts;
    private List<ContactInfo> selectedContacts;

    public ContactsListAdapter(Context context, List<ContactInfo> contacts) {
        this.context = context;
        this.contacts = contacts;
        selectedContacts = new ArrayList<ContactInfo>();
    }

    public List<ContactInfo> getSelectedContacts() {
        return selectedContacts;
    }

    @Override
    public int getCount() {
        return contacts.size();
    }

    @Override
    public Object getItem(int position) {
        return contacts.get(position);
    }

    @Override
    public long getItemId(int position) {
        return Long.parseLong(contacts.get(position).id);
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        ViewHolder holder = new ViewHolder();


        if(convertView == null) {
            convertView = inflater.inflate(R.layout.contacts_list_row_item, null);
            holder.view = (LinearLayout) convertView.findViewById(R.id.llContactRow);
            holder.contactPicture = (CircularImageView) convertView.findViewById(R.id.ivContactPicture);
            holder.name = (TextView) convertView.findViewById(R.id.tvContactName);
            holder.number = (TextView) convertView.findViewById(R.id.tvContactNumber);
            holder.checkbox = (CheckBox) convertView.findViewById(R.id.cbMultipleSelect);
            holder.selectedTick = (ImageView) convertView.findViewById(R.id.ivContactSelectionTick);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final ViewHolder finalHolder = holder;

        holder.name.setText(contacts.get(position).name);
        holder.number.setText(contacts.get(position).number);
        holder.checkbox.setChecked(selectedContacts.contains(contacts.get(position)));

        holder.view.setOnClickListener(new OnClickListener() { 

            @Override 
            public void onClick(View v) {
                finalHolder.checkbox.setChecked(!finalHolder.checkbox.isChecked());
                if(finalHolder.checkbox.isChecked()) {
                    finalHolder.view.setBackgroundColor(Color.parseColor("#33b5e5"));
                    finalHolder.name.setTextColor(Color.WHITE);
                    finalHolder.number.setTextColor(Color.WHITE);
                    //finalHolder.selectedTick.setVisibility(View.VISIBLE);
                    selectedContacts.add(contacts.get(position)); 
                } else {
                    finalHolder.view.setBackgroundColor(Color.TRANSPARENT);
                    finalHolder.name.setTextColor(Color.BLACK);
                    finalHolder.number.setTextColor(Color.BLACK);
                    //finalHolder.selectedTick.setVisibility(View.INVISIBLE);
                    selectedContacts.remove(contacts.get(position));
                } 
            } 
        });

        return convertView;
    }

    private static class ViewHolder {
        LinearLayout view;
        CircularImageView contactPicture;
        CheckBox checkbox;
        TextView name;
        TextView number;
        ImageView selectedTick;
    }
}

リストアイテムをクリックすると背景が青色に変わりますが、リストビューを下にスクロールすると、他のリストアイテムも青色の背景になります。ビュー ホルダー パターンを使用していますが、なぜ機能しないのですか? なぜそれはまだ繰り返されているのですか?私は何か見落としてますか?

前もって感謝します。

更新:コードを少し修正できましたが、まだ問題が残っています。上部からいくつかのリスト項目を選択するとビューがリサイクルされなくなりましたが、下にスクロールして戻ってくると、選択したビューが選択解除されたのではなく、余分なビューが選択されていません。一方、リストビューの下部からいくつかのリスト項目を選択して上にスクロールすると、それらがリサイクルされていることがわかります。なぜそれが起こっているのかわかりません。助けてください。

これが私の更新されたコードです:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    final ContactInfo contact = contacts.get(position);
    final ViewHolder holder;

    if(convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        holder = new ViewHolder();

        convertView = inflater.inflate(R.layout.contacts_list_row_item, null);
        holder.view = (LinearLayout) convertView.findViewById(R.id.llContactRow);
        holder.contactPicture = (CircularImageView) convertView.findViewById(R.id.ivContactPicture);
        holder.name = (TextView) convertView.findViewById(R.id.tvContactName);
        holder.number = (TextView) convertView.findViewById(R.id.tvContactNumber);
        holder.selectedTick = (ImageView) convertView.findViewById(R.id.ivContactSelectionTick);
        convertView.setTag(holder);

        holder.view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if(!selectedContacts.contains(contact)) {
                    setListItemSelected(holder);
                    selectedContacts.add(contact);
                } else {
                    setListItemUnselected(holder);
                    selectedContacts.remove(contact);
                }

                for(ContactInfo con : selectedContacts){
                    Log.d("Adapter", con.name);
                }
            }
        });

    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    if(!selectedContacts.contains(contact)) {
        setListItemUnselected(holder);
    }

    holder.name.setText(contact.name);
    holder.number.setText(contact.number);

    return convertView;
}

private void setListItemSelected(ViewHolder holder) {
    holder.view.setBackgroundColor(Color.parseColor("#33b5e5"));
    holder.name.setTextColor(Color.WHITE);
    holder.number.setTextColor(Color.WHITE);
    holder.selectedTick.setVisibility(View.VISIBLE);
}

private void setListItemUnselected(ViewHolder holder) {
    holder.view.setBackgroundColor(Color.TRANSPARENT);
    holder.name.setTextColor(Color.BLACK);
    holder.number.setTextColor(Color.BLACK);
    holder.selectedTick.setVisibility(View.INVISIBLE);
}
4

4 に答える 4

0

最初に を削除final ViewHolder finalHolder = holder; し、getView(...) でこれを試してください:

holder.view.setOnClickListener(new OnClickListener() { 

        @Override 
        public void onClick(View v) {
            ViewHolder holder = (ViewHolder)v.getTag();

            holder.checkbox.setChecked(!holder.checkbox.isChecked());
            if(holder.checkbox.isChecked()) {
                holder.view.setBackgroundColor(Color.parseColor("#33b5e5"));
                holder.name.setTextColor(Color.WHITE);
                holder.number.setTextColor(Color.WHITE);
                //holder.selectedTick.setVisibility(View.VISIBLE);
                selectedContacts.add(contacts.get(position)); 
            } else {
                holder.view.setBackgroundColor(Color.TRANSPARENT);
                holder.name.setTextColor(Color.BLACK);
                holder.number.setTextColor(Color.BLACK);
                //holder.selectedTick.setVisibility(View.INVISIBLE);
                selectedContacts.remove(contacts.get(position));
            } 
        }
于 2015-03-06T10:26:45.743 に答える
0

boolean[] 配列を使用し、クリック時のメソッドで getView メソッドによって取得される特定の位置を true に設定します

私はそれがあなたを助けると思います

于 2015-03-03T18:41:46.403 に答える