代码之家  ›  专栏  ›  技术社区  ›  LoneWolfPR

安卓:自定义ListView解决了一些奇怪的问题

  •  2
  • LoneWolfPR  · 技术社区  · 15 年前

    我有一个列表视图,我现在正在填充伪字符串。它目前有10件物品,但视图本身只够显示5件。所以列表当然要滚动。我使用以下代码构建了列表:

    列表视图:

    <RelativeLayout
        android:id="@+id/catList"
        android:layout_width="wrap_content"
        android:layout_height="216dip"
        android:layout_marginTop="120dip"
        >
        <ListView
            android:id="@+id/categoryList"
            android:layout_width="308dip"
            android:layout_height="216dip"
            android:layout_marginLeft="6dip"
            android:background="#ffffff"
            android:divider="#ffffff"
            android:choiceMode="singleChoice"
            android:cacheColorHint="#00000000"
    
            >
        </ListView>
        <ImageView
            android:id="@+id/catListFrame"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"    
            android:layout_alignParentTop="true"
            android:src="@drawable/selectorframe"
            />
    </RelativeLayout>
    

    所以基本上列表周围有一个图像框。这些都嵌套在另一个布局中。

    我还有一个自定义的项目xml文件,看起来像这样:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="fill_parent"
       android:layout_height="?android:attr/listPreferredItemHeight"
       android:padding="10dip"
       android:background="#ffffff"
       >
       <TextView
           android:id="@+id/catTitle"
           android:layout_width="fill_parent"
           android:layout_height="fill_parent"
           android:textSize="20dip"
           android:textColor="#000000"
       >
       </TextView>
     </LinearLayout>
    

    以下是让一切正常工作的java:

    private void setCategoryControls(){
        btnBackHome = (ImageView)findViewById(R.id.catHomeBtn);
        btnBackHome.setOnClickListener(goHome);
        catList = (ListView)findViewById(R.id.categoryList);
        catList.setOnItemClickListener(selectCat);
        demoCats = new ArrayList<String>();
        for(int i=1;i<=10;i++){
            demoCats.add("Item " + i);
        }
        m_catAdapter = new CatAdapter(this,R.layout.catitem,demoCats);
        catList.setAdapter(m_catAdapter);
    
    }
    
    private OnItemClickListener selectCat = new OnItemClickListener(){
        public void onItemClick(AdapterView<?> a, View v, int position, long id){
            if(selCatView!=null){
                selCatView.setBackgroundColor(Color.parseColor("#ffffff"));
            }
            v.setBackgroundColor(Color.parseColor("#ffaa00"));
            selCatView = v;
        }
    };
    private class CatAdapter extends ArrayAdapter<String>{
    
        private ArrayList<String> items;
    
        public CatAdapter(Context context, int textViewResourceId, ArrayList<String> items){
            super(context, textViewResourceId, items);
            this.items = items;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.catitem, null);
                }
                String cat = items.get(position);
                if (cat != null) {
                        TextView catName = (TextView) v.findViewById(R.id.catTitle);
                        if (catName != null) {
                              catName.setText(cat);
                        }
    
                }
                return v;
        }
    }
    

    当我点击列表中的一个项目时,它应该只改变该项目的背景色,而不是突出显示两个项目(一个是可见的,一个是我必须滚动到的),大多数时候它甚至不是正确的项目。此外,如果我在突出显示某个项目时滚动,当我在屏幕上滚动突出显示的项目时,它会随机改变突出显示的项目。如果非要我猜的话,我会说这与ListView显然只跟踪可见的孩子这一事实有关。尽管它有一个带有10个项目的适配器,但如果我在列表视图上运行getChildCount,它只会显示5或6,这取决于一个项目是否部分可见,但它不会显示多于或少于可见项目的数量。

    1 回复  |  直到 15 年前
        1
  •  0
  •   Jean    15 年前

    实际上,ListView只跟踪当前显示的子项。这就是为什么在getView方法中循环使用视图。

    最简单的方法就是给你的观点一个状态列表,作为背景。使一个XML状态列表可绘制,其中包含一个state_pressed和一个默认状态(可选的是一个state_focused),并将其作为可绘制的背景 catitem 。当然,您还需要删除手动执行的代码=)

    更多关于状态列表的文档 here 和 here .