Introduction to this section:
In this section, we continue to learn the UI controls we haven't finished yet. Reviewing the previous section, we introduced the concept of Adapter, and then learned the use of the three simplest adapters:
ArrayAdapter, SimpleAdapter, and SimpleCursorAdapter. In this section, we will explain the first UI control that needs to be used with an Adapter: ListView, although it was replaced by the new control RecyclerView in later versions!
As one of the most commonly used controls, the list is still worth studying carefully. In this section, we will learn ListView from a beginner's perspective, including its properties and a simple definition of BaseAdapter. As for ListView optimization, we will take it step by step ~ Don't worry!
1. The simplest example of customizing BaseAdapter and binding it to ListView
First, let's look at the effect diagram we want to achieve:

A very simple ListView, write your own Item, then load some data. Below are the key code snippets:
Animal.java:
/**
* Created by Jay on 2015/9/18 0018.
*/
public class Animal {
private String aName;
private String aSpeak;
private int aIcon;
public Animal() {
}
public Animal(String aName, String aSpeak, int aIcon) {
this.aName = aName;
this.aSpeak = aSpeak;
this.aIcon = aIcon;
}
public String getaName() {
return aName;
}
public String getaSpeak() {
return aSpeak;
}
public int getaIcon() {
return aIcon;
}
public void setaName(String aName) {
this.aName = aName;
}
public void setaSpeak(String aSpeak) {
this.aSpeak = aSpeak;
}
public void setaIcon(int aIcon) {
this.aIcon = aIcon;
}
}
AnimalAdapter.java: Custom BaseAdapter:
/**
* Created by Jay on 2015/9/18 0018.
*/
public class AnimalAdapter extends BaseAdapter {
private LinkedList<Animal> mData;
private Context mContext;
public AnimalAdapter(LinkedList<Animal> mData, Context mContext) {
this.mData = mData;
this.mContext = mContext;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false);
ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName);
TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak);
img_icon.setBackgroundResource(mData.get(position).getaIcon());
txt_aName.setText(mData.get(position).getaName());
txt_aSpeak.setText(mData.get(position).getaSpeak());
return convertView;
}
}
Finally,MainActivity.java:
public class MainActivity extends AppCompatActivity {
private List<Animal> mData = null;
private Context mContext;
private AnimalAdapter mAdapter = null;
private ListView list_animal;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
list_animal = (ListView) findViewById(R.id.list_animal);
mData = new LinkedList<Animal>();
mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog));
mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow));
mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck));
mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish));
mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse));
mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext);
list_animal.setAdapter(mAdapter);
}
}
Okay, customizing BaseAdapter and completing data binding is just that simple~
Don't ask me for the example code; when you first start learning, you'll be able to write this code. I'm just demonstrating the process to get everyone familiar with it~ In addition, it also prepares for the property verification below~
2. Settings for header and footer dividers:
As a list control, ListView, like ordinary lists, allows you to set the header and footer, as well as dividers. The properties available for us to set are as follows:
- footerDividersEnabled: Whether to draw a divider before the footerView (footer), default is true
- headerDividersEnabled: Whether to draw a divider before the headerView (header), default is true
- divider: Set the divider. You can use a color or a drawable resource for the divider.
- dividerHeight: Set the height of the divider
After searching through the API, I found that there is no property that can directly set the header or footer of a ListView. It can only be set by writing code in Java. The methods available for us to call are as follows:
- addHeaderView(View v): Add a headView (header); the parameter in the parentheses is a View object
- addFooterView(View v): Add a footerView (footer); the parameter in the parentheses is a View object
- addHeaderView(headView, null, false): Compared with the previous one, this sets whether the Header can be selected
- addFooterView(View,view,false): Same as above
By the way, the addHeaderView method must be placed before listview.setAdapter, otherwise an error will be reported.
Usage example:
Running effect diagram:

Code implementation:
First, write the layout for the header and footer:
view_header.xml(Header). The footer is the same, so I won't paste it:
<?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="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:textSize="18sp"
android:text="表头"
android:gravity="center"
android:background="#43BBEB"
android:textColor="#FFFFFF"/>
</LinearLayout>
MainActivty.java:
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
private List<Animal> mData = null;
private Context mContext;
private AnimalAdapter mAdapter = null;
private ListView list_animal;
private LinearLayout ly_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
list_animal = (ListView) findViewById(R.id.list_animal);
//动态加载顶部View和底部View
final LayoutInflater inflater = LayoutInflater.from(this);
View headView = inflater.inflate(R.layout.view_header, null, false);
View footView = inflater.inflate(R.layout.view_footer, null, false);
mData = new LinkedList<Animal>();
mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog));
mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow));
mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck));
mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish));
mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse));
mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext);
//添加表头和表尾需要写在setAdapter方法调用之前!!!
list_animal.addHeaderView(headView);
list_animal.addFooterView(footView);
list_animal.setAdapter(mAdapter);
list_animal.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(mContext,"你点击了第" + position + "项",Toast.LENGTH_SHORT).show();
}
}
Okay, the code is still relatively simple. From the above, we can see one issue to pay attention to, namely:
After adding the header and footer, we find that the position is calculated from the header. That is, the original position of the first data you added was 0, but now it becomes 1, because the header also counts!!
3. List starts displaying from the bottom: stackFromBottom
If you want the list to display the bottom of your list, you can use this property and set the stackFromBottom property to true. The effect after setting is as follows:

4. Set click color cacheColorHint
If you set an image as the Background for ListView, when you drag or click an empty area of the ListView, you will find that the items all turn black. At this time, we can use thiscacheColorHintSet the color to transparent: #00000000
5. Hide scrollbar
We can solve this problem by setting: android:scrollbars="none" or setVerticalScrollBarEnabled(true);
Summary of this section:
Okay, that's about all the basic usage of ListView. Of course, besides the properties mentioned above, there are others. Look them up when you actually encounter them~ For now, just know how to override BaseAdapter and complete data binding. In the next section, we will teach you how to optimize the writing of this BaseAdapter~