Basic Use of ListView and Caching Principle

Keywords: Android xml encoding Java

Simple use

 

  1. Add Listview control to set related properties
  2. Use system adapters or custom adapters as appropriate
    1. Custom adapter needs to add item layout first
    2. Binding data to adapters
  3. Associate list view with adapter to display list data

 

Simple code presentation

 

Follow these steps to give the code

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="www.yfg.com.listviewtest.MainActivity">

<ListView
    android:id="@+id/test_lv"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</ListView>

</LinearLayout>

custom adapter

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content">



    <ImageView

        android:id="@+id/item_img"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:src="@mipmap/ic_launcher"/>



    <TextView

        android:id="@+id/item_tv"

        android:layout_marginLeft="10dp"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="center_vertical"

        android:text="123"/>



</LinearLayout>
package www.yfg.com.listviewtest;



import android.content.Context;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.ImageView;

import android.widget.TextView;



import java.util.List;



/**

 * @version: v1.0

 * @description:

 * @package: www.yfg.com.listviewtest

 * @author: yfg

 * @date :2019/7/8

 */



public class FruitAdapter extends ArrayAdapter<Fruit> {



    private int mInt;



    public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {

        super(context, resource, objects);

        mInt = resource;

    }



    @NonNull

    @Override

    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        Fruit fruit = getItem(position);



        View view;

        ViewHolder viewHolder;

        if (convertView == null) {

            view = LayoutInflater.from(getContext()).inflate(mInt, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.mImageView = view.findViewById(R.id.item_img);

            viewHolder.mTextView = view.findViewById(R.id.item_tv);

            view.setTag(viewHolder);

        }else {

            view = convertView;

            viewHolder = (ViewHolder) view.getTag();

        }

        viewHolder.mImageView.setImageResource(fruit.imageId);

        viewHolder.mTextView.setText(fruit.name);



//        View view = LayoutInflater.from(getContext()).inflate(mInt,parent,false);

//        ImageView imageView = view.findViewById(R.id.item_img);

//        TextView textView = view.findViewById(R.id.item_tv);

//        imageView.setImageResource(fruit.imageId);

//        textView.setText(fruit.name);





        return view;

    }



    class ViewHolder {



        ImageView mImageView;

        TextView mTextView;



    }

}

Final presentation

initFruits();

FruitAdapter adapter = new FruitAdapter(MainActivity.this,R.layout.layout_fruit_item,mFruitList);

ListView listView = findViewById(R.id.test_lv);

listView.setAdapter(adapter);



listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        Fruit fruit = mFruitList.get(position);

        Toast.makeText(MainActivity.this, fruit.name, Toast.LENGTH_SHORT).show();

    }

});

Notes for ListView Use

 

1. Because of the problem of layout reuse, some attributes of item must be embodied in the code, otherwise the setting of attributes may not achieve the desired effect.

For example, depending on the data source, determine the visibility of a control in item

 

2.item layout should not set default values for controls that take values from data sources. Otherwise, there may be problems in data source processing, and the display of pages can not be found in the first place.

For example, the assignment of textview

 

 

Adapter's getView method goes deep

 

The annotation part of the above code can also implement functions, but there are performance defects. Every getView loads the layout and carries out fbi. Looking at our implementation code, we use convertView, which is a parameter that caches the previously loaded layout for reuse, and then we introduce one. There are three internal classes, which gather views in item and process them uniformly in fbi. The setTag and getTag methods of view are used to associate the control of item with the parent layout, so as to judge when getView is made, so caching can be used to improve efficiency.

 

The Caching Mechanism of ListView

 

Reference Blog;

https://zhuanlan.zhihu.com/p/23339185

https://www.cnblogs.com/RGogoing/p/5554086.html

 

When will caching be used?

That is, when convertView in the above Adapter is not empty, take a chestnut. When list data is large, when we slide down, there will be an item at the top invisible, and a new item at the bottom, then caching will be used. If there is less data, the screen is not full, will caching be used? The answer is also used. Of course, if we use refresh and other operations, there will also be the use of caching.

 

How to use caching? (Caching Principle)

Here we need to clarify the concept of ActiveView. ActiveView is actually an onScreenView that is visible on the UI screen and also an interactive view with users. Then these views will be stored directly into mActiveViews through RecycleBin for direct reuse. When we slide ListView, there are some V's. When an iew is slid out of the screen, these views become ScrapViews, or abandoned Views, which are no longer able to interact with users, so there is no need to draw these useless views when the UI view changes. He will be stored in the mScrapViews by RecycleBin, but not destroyed, for the purpose of secondary reuse, that is, indirect reuse. When a new view needs to be displayed, we first determine whether there exists in m ActivityView. If there exists, we can directly extract the reuse from mActiveViews, that is, direct reuse. Otherwise, we can judge from mScrapViews. If there exists, we can reuse the current view twice. If there is no reuse, then You need inflate View.

 

 

This is the two-level reuse of ListView. It introduces several key classes, variables and methods.

 

ListView class, layoutChildren method loads layout, fillDown method draws the first item

The AbsListView class, the parent of ListView, and the onLayout method are used to load the layout.

RecycleBin class, AbsListView internal class, key reuse class

 

Source code analysis (focus only)

 

RecycleBin class

 

 

AbsListView class

 

ListView class, find a way to draw the first item

 

 

 

Core code for reuse: (focusing on mRecycler's approach)

 

 

 

Notes on Caching

 

1. Generally, when the screen displays 10 data and (the screen can display 10 data, just full), it is directly multiplexed and multiplexed from mActiveViews, because all data is stored in mActiveViews after the first loading, and when pulled down, the eleventh data appears, but nine of them are duplicated. The eleventh data is obtained from mScrapViews, but the data has been erased. We need to consider the extreme situation. When the first one is not completely visible and the eleventh one needs to be loaded, we must use the inflate method of getView.

 

2. ViewHolder just eliminates unnecessary fbi and has nothing to do with the reuse mechanism

 

 

Written in the final comment

 

Why don't you specify the source code in detail? I don't think it's necessary because I forgot it too quickly. I wrote a lot of source code analysis in front of me. I can't remember it completely unless I comb it out from scratch again. So, are there any good suggestions here?

 

 

Posted by jasonX on Tue, 06 Aug 2019 00:49:50 -0700