Home Java javaTutorial Android Talk--Usage of BaseAdapter in ListView

Android Talk--Usage of BaseAdapter in ListView

Dec 13, 2016 pm 04:41 PM
android

After developing and using various Adapters, the one I feel most comfortable using is BaseAdapter. Although it is a little more troublesome to use than other adapters, you can use it to achieve many of your favorite list layouts, such as ListView, GridView, Gallery, Spinner, etc. . It is directly inherited from the interface class Adapter. When using BaseAdapter, you need to rewrite many methods, the most important of which is getView, because this will involve issues such as ListView optimization. For other methods, please refer to the linked article

BaseAdapter and Others Adapter is a little different. Other Adapters can set data directly in their construction methods, such as

SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.list_item, new String[]{"img","title","info",newint[]{R.id.img, R.id.title, R.id.info}});
Copy after login

. But in BaseAdapter, you need to implement a class inherited from BaseAdapter and rewrite many methods in it, such as

class MyAdapter extends BaseAdapter 
    { 
        private Context context; 
        public MyAdapter(Context context) 
        { 
            this.context = context; 
        } 
        @Override 
        publicint getCount() { 
            // How many items are in the data set represented by this Adapter.(在此适配器中所代表的数据集中的条目数) 
            return0; 
        } 
 
        @Override 
        public Object getItem(int position) { 
            // Get the data item associated with the specified position in the data set.(获取数据集中与指定索引对应的数据项) 
            returnnull; 
        } 
 
        @Override 
        publiclong getItemId(int position) { 
            // Get the row id associated with the specified position in the list.(取在列表中与指定索引对应的行id) 
            return0; 
        } 
 
        @Override 
        public View getView(int position, View convertView, ViewGroup parent) { 
            // Get a View that displays the data at the specified position in the data set. 
            returnnull; 
        } 
         
    }
Copy after login

this There is nothing difficult in it, but this getView method must be handled carefully, which is also the most troublesome. The first type: there is no processing, and it is not recommended to write like this. If the amount of data is small, it will be fine, but if the amount of data in the list item is large, the View will be re-created every time and the resources will be set, seriously affecting the performance, so don’t use this method from the beginning

@Override 
        public View getView(int position, View convertView, ViewGroup parent) { 
            View item = mInflater.inflate(R.layout.list_item, null); 
            ImageView img = (ImageView)item.findViewById(R.id.img)  
            TextView title = (TextView)item.findViewById(R.id.title); 
            TextView info = (TextView)item.findViewById(R.id.info); 
            img.setImageResource(R.drawable.ic_launcher); 
            title.setText("Hello"); 
            info.setText("world"); 
             
            return item; 
        }
Copy after login

The second method ListView optimization: By caching convertView, this method of using cached contentView can determine if the View does not exist in the cache before creating the View. If it already exists, you can use the View in the cache to improve performance

public View getView(int position, View convertView, ViewGroup parent) { 
            if(convertView == null) 
            { 
                convertView = mInflater.inflate(R.layout.list_item, null); 
            } 
             
            ImageView img = (ImageView)convertView.findViewById(R.id.img)  
            TextView title = (TextView)convertView.findViewById(R.id.title); 
            TextView info = (TextView)ConvertView.findViewById(R.id.info); 
            img.setImageResource(R.drawable.ic_launcher); 
            title.setText("Hello"); 
            info.setText("world"); 
             
            return convertView; 
        }
Copy after login

The third ListView optimization: through convertView +ViewHolder to achieve, ViewHolder is a static class, the key benefit of using ViewHolder is to cache the view (View) that displays data, speeding up the response speed of the UI.

When we judge convertView == null , if it is empty, we will assign a value to the convertView according to the designed Item layout (XML) of the List, and generate a viewHolder to bind each View control in the convertView (XML those controls in the layout). Then use convertView's setTag to set the viewHolder to the Tag so that it can be taken out of the Tag when the system draws the ListView for the second time. (See the code below)

If convertView is not empty, convertView's getTag() will be used directly to obtain a ViewHolder.

//在外面先定义,ViewHolder静态类 
    staticclass ViewHolder 
    { 
        public ImageView img; 
        public TextView title; 
        public TextView info; 
    } 
//然后重写getView 
        @Override 
        public View getView(int position, View convertView, ViewGroup parent) { 
            ViewHolder holder; 
            if(convertView == null) 
            { 
                holder = new ViewHolder(); 
                convertView = mInflater.inflate(R.layout.list_item, null); 
                holder.img = (ImageView)item.findViewById(R.id.img)  
                holder.title = (TextView)item.findViewById(R.id.title); 
                holder.info = (TextView)item.findViewById(R.id.info); 
                convertView.setTag(holder); 
            }else 
            { 
                holder = (ViewHolder)convertView.getTag(); 
                holder.img.setImageResource(R.drawable.ic_launcher); 
                holder.title.setText("Hello"); 
                holder.info.setText("World"); 
            } 
             
            return convertView; 
        }
Copy after login

At this point, someone may ask what is the difference between ViewHolder static class combined with caching convertView and using convertView directly? Is it repeated?

Here, the official explanation is given

Two methods to improve Adapter

To work efficiently the adapter implemented here uses two techniques: -It reuses the convertView passed to getView() to avoid inflating View when it is not necessary

(Translation: reuse cache convertView passed to getView() method to avoid filling unnecessary views) -It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary

(Translation: Use the ViewHolder pattern to avoid unnecessary calls to findViewById(): because too many findViewById will also affect performance) The role of the ViewHolder class - The ViewHolder pattern consists in storing a data structure in the tag of the view returned by getView().This data structures contains references to the views we want to bind data to, thus avoiding calling to findViewById() every time getView() is invoked

(Translation: ViewHolder mode stores a data structure in the tag of the view returned by the getView() method. This data structure contains a reference to the view to which we

want to bind data, thereby avoiding calling getView every time () when calling findViewById())

Example 1: Use BaseAdapter to customize the ListView layout

main.xml

<?xmlversion="1.0"encoding="utf-8"?> 
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 
 
    <ListView 
        android:id="@+id/lv" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:fastScrollEnabled="true" 
        /> 
 
</LinearLayout>
Copy after login

list_item.xml

<?xmlversion="1.0"encoding="utf-8"?> 
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal"> 
 
    <ImageView 
        android:id="@+id/img" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        /> 
    <LinearLayout  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:orientation="vertical" 
        > 
        <TextView 
            android:id="@+id/tv" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:textSize="20sp" 
        /> 
        <TextView  
            android:id="@+id/info" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:textSize="14sp" 
            /> 
    </LinearLayout> 
     
 
</LinearLayout>
Copy after login

Activity

package com.loulijun.demo17; 
 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
 
import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.TextView; 
 
publicclass Demo17Activity extends Activity { 
    private ListView lv; 
    private List<Map<String, Object>> data; 
    @Override 
    publicvoid onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        lv = (ListView)findViewById(R.id.lv); 
        //获取将要绑定的数据设置到data中 
        data = getData(); 
        MyAdapter adapter = new MyAdapter(this); 
        lv.setAdapter(adapter); 
    } 
     
    private List<Map<String, Object>> getData() 
    { 
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); 
        Map<String, Object> map; 
        for(int i=0;i<10;i++) 
        { 
            map = new HashMap<String, Object>(); 
            map.put("img", R.drawable.ic_launcher); 
            map.put("title", "跆拳道"); 
            map.put("info", "快乐源于生活..."); 
            list.add(map); 
        } 
        return list; 
    } 
     
    //ViewHolder静态类 
    staticclass ViewHolder 
    { 
        public ImageView img; 
        public TextView title; 
        public TextView info; 
    } 
     
    publicclass MyAdapter extends BaseAdapter 
    {     
        private LayoutInflater mInflater = null; 
        private MyAdapter(Context context) 
        { 
            //根据context上下文加载布局,这里的是Demo17Activity本身,即this 
            this.mInflater = LayoutInflater.from(context); 
        } 
 
        @Override 
        publicint getCount() { 
            //How many items are in the data set represented by this Adapter. 
            //在此适配器中所代表的数据集中的条目数 
            return data.size(); 
        } 
 
        @Override 
        public Object getItem(int position) { 
            // Get the data item associated with the specified position in the data set. 
            //获取数据集中与指定索引对应的数据项 
            return position; 
        } 
 
        @Override 
        publiclong getItemId(int position) { 
            //Get the row id associated with the specified position in the list. 
            //获取在列表中与指定索引对应的行id 
            return position; 
        } 
         
        //Get a View that displays the data at the specified position in the data set. 
        //获取一个在数据集中指定索引的视图来显示数据 
        @Override 
        public View getView(int position, View convertView, ViewGroup parent) { 
            ViewHolder holder = null; 
            //如果缓存convertView为空,则需要创建View 
            if(convertView == null) 
            { 
                holder = new ViewHolder(); 
                //根据自定义的Item布局加载布局 
                convertView = mInflater.inflate(R.layout.list_item, null); 
                holder.img = (ImageView)convertView.findViewById(R.id.img); 
                holder.title = (TextView)convertView.findViewById(R.id.tv); 
                holder.info = (TextView)convertView.findViewById(R.id.info); 
                //将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag 
                convertView.setTag(holder); 
            }else 
            { 
                holder = (ViewHolder)convertView.getTag(); 
            } 
            holder.img.setBackgroundResource((Integer)data.get(position).get("img")); 
            holder.title.setText((String)data.get(position).get("title")); 
            holder.info.setText((String)data.get(position).get("info")); 
             
            return convertView; 
        } 
         
    } 
}
Copy after login

The running results are as follows:

Android Talk--Usage of BaseAdapter in ListViewExample 2: Apply BaseAdapter

main.xml

<?xmlversion="1.0"encoding="utf-8"?> 
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 
     
    <ImageView  
        android:id="@+id/img" 
        android:layout_width="480px" 
        android:layout_height="480px" 
        android:layout_gravity="center" 
        /> 
    <Gallery  
        android:id="@+id/gallery" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:spacing="3dp" 
        android:layout_gravity="bottom" 
        /> 
 
</LinearLayout>
Copy after login

Activity on Gallery: getView in this part has not been optimized, and it has not been adjusted after debugging for a long time. For the time being, the most basic method is still used. I will find a special time to write about the memory leak in Gallery, because when there are a lot of image resources, it will cause out of memory errors

package com.loulijun.demo16; 
 
import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.BaseAdapter; 
import android.widget.Gallery; 
import android.widget.ImageView; 
 
publicclass Demo16Activity extends Activity { 
    private Gallery mGallery; 
    private ImageView mImg; 
    //图片数组 
    privateint[] pics = { 
            R.drawable.pic1, 
            R.drawable.pic2, 
            R.drawable.pic3, 
            R.drawable.pic4, 
            R.drawable.pic5, 
            R.drawable.pic6 
    }; 
    @Override 
    publicvoid onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        mImg = (ImageView)findViewById(R.id.img); 
        mGallery = (Gallery)findViewById(R.id.gallery); 
        MyAdapter adapter = new MyAdapter(this); 
        mGallery.setAdapter(adapter); 
        mGallery.setOnItemClickListener(new Gallery.OnItemClickListener() 
        { 
 
            @Override 
            publicvoid onItemClick(AdapterView<?> adapter, View view, int position, 
                    long arg3) { 
                mImg.setImageResource(pics[position]); 
            } 
             
        }); 
    } 
     
    //内部类 
    class MyAdapter extends BaseAdapter 
    { 
        //用来接收传递过来的Context上下文对象 
        private Context context; 
 
        //构造函数 
        public MyAdapter(Context context) 
        { 
            this.context = context; 
        } 
        @Override 
        publicint getCount() { 
            //返回图片数组大小 
            return pics.length; 
        } 
 
        @Override 
        public Object getItem(int position) { 
            //根据选中项返回索引位置 
            return position; 
        } 
 
        @Override 
        publiclong getItemId(int position) { 
            //根据选中项id返回索引位置 
            return position; 
        } 
        //未优化的getView,这部分可以使用recycle()释放内存、或者BitmapFacotry.Options缩小,或者软引用,或者控制图片资源大小等等很多方法,找时间专门写 
        @Override 
        public View getView(int position, View convertView, ViewGroup parent) { 
            ImageView img = new ImageView(context); 
            img.setAdjustViewBounds(true); 
            img.setImageResource(pics[position]); 
            img.setScaleType(ImageView.ScaleType.FIT_XY); 
            img.setLayoutParams(new Gallery.LayoutParams(120,120)); 
             
            return img; 
        }     
    } 
}
Copy after login

Operation effect: The principle is the same, but there will be a difference when the layout is loaded, but Just this small difference is annoying enough

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades Sep 12, 2024 pm 12:23 PM

In recent days, Ice Universe has been steadily revealing details about the Galaxy S25 Ultra, which is widely believed to be Samsung's next flagship smartphone. Among other things, the leaker claimed that Samsung only plans to bring one camera upgrade

Samsung Galaxy S25 Ultra leaks in first render images with rumoured design changes revealed Samsung Galaxy S25 Ultra leaks in first render images with rumoured design changes revealed Sep 11, 2024 am 06:37 AM

OnLeaks has now partnered with Android Headlines to provide a first look at the Galaxy S25 Ultra, a few days after a failed attempt to generate upwards of $4,000 from his X (formerly Twitter) followers. For context, the render images embedded below h

IFA 2024 | TCL\'s NXTPAPER 14 won\'t match the Galaxy Tab S10 Ultra in performance, but it nearly matches it in size IFA 2024 | TCL\'s NXTPAPER 14 won\'t match the Galaxy Tab S10 Ultra in performance, but it nearly matches it in size Sep 07, 2024 am 06:35 AM

Alongside announcing two new smartphones, TCL has also announced a new Android tablet called the NXTPAPER 14, and its massive screen size is one of its selling points. The NXTPAPER 14 features version 3.0 of TCL's signature brand of matte LCD panels

Vivo Y300 Pro packs 6,500 mAh battery in a slim 7.69 mm body Vivo Y300 Pro packs 6,500 mAh battery in a slim 7.69 mm body Sep 07, 2024 am 06:39 AM

The Vivo Y300 Pro just got fully revealed, and it's one of the slimmest mid-range Android phones with a large battery. To be exact, the smartphone is only 7.69 mm thick but features a 6,500 mAh battery. This is the same capacity as the recently launc

Samsung Galaxy S24 FE billed to launch for less than expected in four colours and two memory options Samsung Galaxy S24 FE billed to launch for less than expected in four colours and two memory options Sep 12, 2024 pm 09:21 PM

Samsung has not offered any hints yet about when it will update its Fan Edition (FE) smartphone series. As it stands, the Galaxy S23 FE remains the company's most recent edition, having been presented at the start of October 2023. However, plenty of

New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades Sep 12, 2024 pm 12:22 PM

In recent days, Ice Universe has been steadily revealing details about the Galaxy S25 Ultra, which is widely believed to be Samsung's next flagship smartphone. Among other things, the leaker claimed that Samsung only plans to bring one camera upgrade

Xiaomi Redmi Note 14 Pro Plus arrives as first Qualcomm Snapdragon 7s Gen 3 smartphone with Light Hunter 800 camera Xiaomi Redmi Note 14 Pro Plus arrives as first Qualcomm Snapdragon 7s Gen 3 smartphone with Light Hunter 800 camera Sep 27, 2024 am 06:23 AM

The Redmi Note 14 Pro Plus is now official as a direct successor to last year'sRedmi Note 13 Pro Plus(curr. $375 on Amazon). As expected, the Redmi Note 14 Pro Plus heads up the Redmi Note 14 series alongside theRedmi Note 14and Redmi Note 14 Pro. Li

iQOO Z9 Turbo Plus: Reservations begin for the potentially beefed-up series flagship iQOO Z9 Turbo Plus: Reservations begin for the potentially beefed-up series flagship Sep 10, 2024 am 06:45 AM

OnePlus'sister brand iQOO has a 2023-4 product cycle that might be nearlyover; nevertheless, the brand has declared that it is not done with itsZ9series just yet. Its final, and possibly highest-end,Turbo+variant has just beenannouncedas predicted. T

See all articles