Android BaseAdapter:位置不是真正的位置?

Posted

技术标签:

【中文标题】Android BaseAdapter:位置不是真正的位置?【英文标题】:Android BaseAdapter : position not really the position? 【发布时间】:2010-10-07 19:47:48 【问题描述】:

当我使用BaseAdapter 的列表视图离开屏幕时,每一行不再保持连续的位置。除了这个,我不知道还能怎么解释。

如果我的 BA/LV 在屏幕上显示 4 个项目,并且我添加了一个显示每一行的 TextView 的视图,它会显示 0、1、2、3 的行号(这是正确的)。但是,一旦我将列表向下滚动到底部的 4 项(第 5-8 项),它就会将它们显示为 4,5,0,1??为什么?

编辑: 我确实发现如果我改变了

rv = (RowView) convertView;

rv =  new RowView(mContext,(cursor.getString(2)),
                        (cursor.getString(5)),
                        cursor.getString(cursor.getColumnIndex(DBHelper.KEY_IMAGEFILENAME)),
                        cursor.getString(cursor.getColumnIndex(DBHelper.KEY_CITY)),position);

它可以工作,但它没有重新使用代码。所以,我想我是在正确的轨道上。我确实尝试了一些方便的方法,但这对我没有太大帮助,因为我需要在构造函数启动之前设置这些值。我是否需要创建一个新方法并在最后触发它?比如addRow方法?这也会导致它滚动非常慢。

          @Override
               public void onCreate(Bundle bundle)
               
                 super.onCreate(bundle);
                 //setContentView(R.layout.findlist);
                 //getListView().setEmptyView(findViewById(R.id.empty));
                 mDbHelper = new DBHelper(this);
                 mDbHelper.open();
                 cursor = mDbHelper.fetchAllLocations();
                 startManagingCursor(cursor);
                 mAdapter = new myListAdapter(this);
                 setListAdapter(mAdapter);
        
               
    public class myListAdapter extends BaseAdapter 
            public String testing;
            public myListAdapter(Context c) 
                mContext = c;
                // TODO Auto-generated constructor stub
            
    
            @Override
            public int getCount() 
                // TODO Auto-generated method stub
                return cursor.getCount();
            
    
            @Override
            public Object getItem(int position) 
                // TODO Auto-generated method stub
                return position;
            
    
            @Override
            public long getItemId(int position) 
                // TODO Auto-generated method stub
                return position;
            
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) 
    
                
                 cursor.moveToPosition(position);
                 RowView rv;
    
    
                 if (convertView == null) 
                        rv = new RowView(mContext,(cursor.getString(2)),
                                (cursor.getString(5)),
                                cursor.getString(cursor.getColumnIndex(DBHelper.KEY_IMAGEFILENAME)),
                                cursor.getString(cursor.getColumnIndex(DBHelper.KEY_CITY)),position);
                     else 
                        rv = (RowView) convertView;
                        try 
              // I KNOW THIS SECTION IS NOT RIGHT, BUT I HAVE BEEN MESSING IN HERE          
                        rv.setAddress(cursor.getString(2));
                        rv.setCity(cursor.getString(5));
                        rv.setFocusable(true);
                        rv.setClickable(true); 
                        catch (Exception e) 
                            rv = (RowView) convertView;
                            rv.setAddress(cursor.getString(2));
                            rv.setCity(cursor.getString(5));
                            rv.setFocusable(true);
                            rv.setClickable(true); 
                            Toast mToast;
                            mToast = Toast.makeText(FindList.this, "Error :" + e.toString() ,
                                    Toast.LENGTH_LONG);
                            mToast.show();
                        
                    
                    
                 return rv;
            
            
            public void addItems() 
    
                 //String[] from = new String[]  DBHelper.KEY_BUSINESSNAME, DBHelper.KEY_ADDRESS, DBHelper.KEY_CITY, DBHelper.KEY_GPSLONG, DBHelper.KEY_GPSLAT,  DBHelper.KEY_IMAGEFILENAME  + "";
                 // create array of values of widgits
                 //to = new int[]  R.id.businessname, R.id.address, R.id.city, R.id.gpslong, R.id.gpslat, R.id.preview;
                 // Now create an array adapter and set it to display using our row from notes_row.xml
                 
                 
            
            
            
            
        


private class RowView extends LinearLayout 
        private TextView mAddress;
        private TextView mCity;
        public ImageView mArrow;
        public ImageView mPicture;
        public String mPathName;
        public String mDateTime;
        public RowView(Context context, String title, String words, String pathName, String city, int position) 
            super(context);

            this.setOrientation(HORIZONTAL);
            this.setVerticalGravity(16); //CENTER_VERTICAL 

            // Here we build the child views in code. They could also have
            // been specified in an XML file.
           
            //DISPLAY DELETE BUTTON
            Button mButton = new Button(context);
            mButton.setFocusable(false);
            mButton.setId(position);
            mButton.setBackgroundResource(R.drawable.delete3);
            addView(mButton, new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            
            TextView mTitle;
            mTitle = new TextView(context);
            mTitle.setText(Integer.toString(position));
            addView(mTitle, new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

            this.setOrientation(HORIZONTAL);      
            
            try 
             Bitmap bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(cursor.getString(cursor.getColumnIndex(DBHelper.KEY_IMAGEFILENAME))),100, 100, true);
                mPicture = new ImageView(context);
                mPicture.setImageBitmap(bm);    
            catch (Exception e)  
                 mPicture = new ImageView(context);
                 mPicture.setImageResource(R.drawable.noimage);
                
            
            addView(mPicture, new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            
            mArrow = new ImageView(context);
            mArrow.setBackgroundResource(R.drawable.arrowleft3);
            addView(mArrow, new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
          
            currentPosition = position;
            Button button = (Button)findViewById(position);
            button.setOnClickListener(mCorkyListener);
            
        

【问题讨论】:

【参考方案1】:

使用 convertView 时,您会看到一个以前使用过但不再显示的视图。您应该注意使用当前项目的值重置其所有属性。否则,您在 RowView 构造函数中设置的所有值都将与您在第一次创建该视图时提供的值保持一致。

为了更好地理解 ListViews,您必须了解它只使用一组有限的 RowViews,仅使用足以填充显示的数量以及在必须显示它们之前将填充您的数据的更多数量。

【讨论】:

以上是关于Android BaseAdapter:位置不是真正的位置?的主要内容,如果未能解决你的问题,请参考以下文章

Android:在两列中显示信息,而不是 BaseAdapter 的一列

如何在android中使用baseadapter刷新自定义列表视图

在使用Baseadapter的Listview中,Android Plus和Minus按钮无法正常工作

Android——BaseAdapter相关

Android:BaseAdapter 怎么用?

Android中BaseAdapter使用基础点