自定义ListView适配器中,按下项目时的高亮效果

8
每次在Android上点击视图时,都会有一个系统可视效果。 在Lollipop中,它是涟漪效果。 当我创建了一个ListView并将其与普通的ArrayAdapter相关联时,这种效果存在。 现在,我已经添加了自定义的ListView,这种效果就消失了。
现在,我尝试确定问题所在,并且由于使用与默认适配器相同的列表项布局效果良好,因此我认为问题出在我的自定义适配器上。
我看到了许多解决方案,这些解决方案与调用某些可绘制层相关,但这不是我要做的。 涟漪效果只会显示因为我在Android 5上运行应用程序,现在我想做的是当我的项目被点击时,具有默认的系统高亮效果。
以下是我的自定义适配器(希望)相关的部分:
public class CustomCardSetsAdapter extends BaseAdapter {
    List<Card> totalList;
    ArrayList<Boolean> hiddenItems;
    ListView parentLV;
    Integer curPosition = -1;

    public static int selectedRowIndex;

    public CustomCardSetsAdapter(CardSets cardList, ListView parentListView)
    {
        this.parentLV = parentListView;
        assignSetValues(cardList);

        totalList =      cardList.getBlackrockMountain();
        totalList.addAll(cardList.getClassic());
        totalList.addAll(cardList.getCurseofNaxxramas());
        totalList.addAll(cardList.getGoblinsvsGnomes());

        Collections.sort(totalList,
                new Comparator<Card>() {
                    public int compare(Card f1, Card f2) {
                        return f1.toString().compareTo(f2.toString());
                    }
                });

        hiddenItems = new ArrayList<>();

        for (int i = 0; i < totalList.size(); i++) {
            if(!totalList.get(i).getCollectible())
                hiddenItems.add(true);
            else
                hiddenItems.add(false);
        }
    }

    @Override
    public int getCount() {
        return (totalList.size() - getHiddenCount());
    }

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        final int index = getRealPosition(position);

        if(convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            convertView = inflater.inflate(R.layout.card_list_item, parentLV, false);
        }

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Integer prevPosition = curPosition;
                curPosition = position;

                if(prevPosition >= parentLV.getFirstVisiblePosition() &&
                        prevPosition <= parentLV.getLastVisiblePosition())
                {
                    View view = parentLV.getChildAt(prevPosition- parentLV.getFirstVisiblePosition());
                    parentLV.getAdapter().getView(prevPosition,view, parentLV);
                }

                v.setBackgroundColor(Color.WHITE);
            }
        });


        Card curCard = totalList.get(index);

        TextView cardName = (TextView) convertView.findViewById(R.id.cardName);
        cardName.setText(curCard.getName());
        setRarityColor(curCard,cardName);

        TextView manaCost = (TextView) convertView.findViewById(R.id.manaCost);
        manaCost.setText((curCard.getCost()).toString());

        ImageView setIcon = (ImageView) convertView.findViewById(R.id.setIcon);
        setSetIcon(curCard,setIcon);

        if(position == curPosition)
            convertView.setBackgroundColor(Color.WHITE);
        else
            convertView.setBackgroundColor(Color.TRANSPARENT);

        return convertView;
    }

    @Override
    public int getItemViewType(int position) {
        return R.layout.card_list_item;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    private int getHiddenCount()
    {
        int count = 0;
        for(int i = 0;i <totalList.size();i++)
            if(hiddenItems.get(i))
                count++;
        return count;
    }

    private int getRealPosition(int position) {
        int hElements = getHiddenCountUpTo(position);
        int diff = 0;
        for(int i=0;i<hElements;i++) {
            diff++;
            if(hiddenItems.get(position+diff))
                i--;
        }
        return (position + diff);
    }

    private int getHiddenCountUpTo(int location) {
        int count = 0;
        for(int i=0;i<=location;i++) {
            if(hiddenItems.get(i))
                count++;
        }
        return count;
    }
}

提前致谢。


你将列表项的背景颜色设置为白色。涟漪的颜色是什么? - alanv
默认情况下,它是灰色加深灰色。但是,如果不改变单元格的背景,效果仍然缺失。 - ZShock
1
你尝试过移除View.OnClickListener,通过AdapterView.OnItemClickListener来处理吗? - alanv
哇,我放了一个 OnItemClickListener 的占位符(一个简单的 Toast),现在这个单元格正在产生效果。我回家后会更深入地研究它。同时...你知道为什么这样行得通吗? - ZShock
ListView 会处理自己的触摸操作。如果你在行本身上设置了点击监听器,ListView 就会认为你正在处理自己的触摸操作。 - alanv
1个回答

9
在您的ListView XML中添加:
 android:drawSelectorOnTop="true"

我认为您可能没有正确使用适配器...在适配器上使用ViewHolder模式:
public class CustomCardSetsAdapter extends BaseAdapter {
    List<Card> totalList;
    ArrayList<Boolean> hiddenItems;
    ListView parentLV;
    Integer curPosition = -1;
    public static int selectedRowIndex;

    private class ViewHolderRow{
        TextView cardName;
        TextView manaCost;
        ImageView setIcon;
    }



   public CustomCardSetsAdapter(CardSets cardList, ListView parentListView)
   {
       this.parentLV = parentListView;
       assignSetValues(cardList);

       totalList =      cardList.getBlackrockMountain();
       totalList.addAll(cardList.getClassic());
       totalList.addAll(cardList.getCurseofNaxxramas());
       totalList.addAll(cardList.getGoblinsvsGnomes());

       Collections.sort(totalList,
            new Comparator<Card>() {
                public int compare(Card f1, Card f2) {
                    return f1.toString().compareTo(f2.toString());
                }
            });

       hiddenItems = new ArrayList<>();

       for (int i = 0; i < totalList.size(); i++) {
           if(!totalList.get(i).getCollectible())
               hiddenItems.add(true);
           else
               hiddenItems.add(false);
       }
    }

    @Override
    public int getCount() {
        return (totalList.size() - getHiddenCount());
    }

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        final int index = getRealPosition(position);
         ViewHolderRow theRow;
        if(convertView == null) {
           theRow = new ViewHolderRow();
           LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            convertView = inflater.inflate(R.layout.card_list_item, parentLV, false);

            // Cache your views
            theRow.cardName = (TextView) convertView.findViewById(R.id.cardName);
            theRow.manaCost = (TextView) convertView.findViewById(R.id.manaCost);
            theRow.setIcon = (ImageView) convertView.findViewById(R.id.setIcon);

            // Set the Tag to the ViewHolderRow
            convertView.setTag(theRow);
        }else{
           // get the Row to re-use
           theRow = (ViewHolderRow) convertView.getTag();
        }

    //... Removed convertView.setOnClickListener  

    Card curCard = totalList.get(index);

    // Set Items
    theRow.cardName.setText(curCard.getName());
    setRarityColor(curCard,theRow.cardName);
    theRow.manaCost.setText((curCard.getCost()).toString());
    setSetIcon(curCard,theRow.setIcon);

       if(position == curPosition){
            convertView.setBackgroundColor(Color.WHITE);
       }else{
            convertView.setBackgroundColor(Color.TRANSPARENT);
       }

        return convertView;
    }

    @Override
    public int getItemViewType(int position) {
        return R.layout.card_list_item;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    private int getHiddenCount()
    {
        int count = 0;
        for(int i = 0;i <totalList.size();i++)
            if(hiddenItems.get(i))
                count++;
         return count;
    }

    private int getRealPosition(int position) {
        int hElements = getHiddenCountUpTo(position);
        int diff = 0;
        for(int i=0;i<hElements;i++) {
            diff++;
            if(hiddenItems.get(position+diff))
                i--;
        }
        return (position + diff);
    }

    private int getHiddenCountUpTo(int location) {
       int count = 0;
       for(int i=0;i<=location;i++) {
             if(hiddenItems.get(i))
                count++;
             }
           return count;
     }
}

建议使用onListItemClickListener替代在整个convertView上使用此项...

yourListView.setOnItemClickListener(ListListener);


private final OnItemClickListener ListListener = new OnItemClickListener{
    @Override
    public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3)     {
          // ... Do something on click       
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接