项目结果演示:
案例实现流程:
在布局文件中新建一个ListView组件
↓
在另一个布局文件中新建一个用于展示的布局文件
↓
在java文件中新建实体类Student
↓
在java文件中新建StudentApdater继承BaseAdapter并覆写相关方法(重点:覆写getView方法)
↓
通过LinkedList插入数据
↓
调用自己定义的适配器应用于ListView组件
代码部分
xml:
activity_base_adapter_demo01.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="@+id/BaseAdapterDemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
student_toupiao_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- android:descendantFocusability="blocksDescendants"
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
-->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 定义一个TextView,用于作为列表项的一部分 -->
<TextView
android:id="@+id/studentName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="#f0f"
android:paddingLeft="10dp"/>
<ProgressBar style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:id="@+id/progressCount"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="100"/>
<!-- 定义一个TextView,用于作为列表项的一部分 -->
<Button
android:id="@+id/btnTouPiao"
android:text="投票"
android:focusable="true"
android:clickable="true"
android:layout_gravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dp"
android:paddingLeft="10dp"/>
</LinearLayout>
</LinearLayout>
java:
BaseAdapterDemo01.java
package com.example.firstapplication.BaseAdapterDemo;
import androidx.appcompat.app.AppCompatActivity;
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.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.firstapplication.R;
import java.util.LinkedList;
public class BaseAdapterDemo01 extends AppCompatActivity {
LinkedList<Student> ll= new LinkedList<Student>();
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_adapter_demo01);
lv = this.findViewById(R.id.BaseAdapterDemo);
ll.add(new Student("张三",0));
ll.add(new Student("李四",0));
ll.add(new Student("王五",0));
StudentApdater adapter = new StudentApdater(ll,this);
lv.setAdapter(adapter);
}
class StudentApdater extends BaseAdapter{
private LinkedList<Student> listStudent;//要显示在该adpter里的数据集合
private Context context;
public StudentApdater(LinkedList<Student> listStudent, Context context) {
this.listStudent = listStudent;
this.context = context;
}
@Override
public int getCount() {
//返回列表的项数
return listStudent.size();
}
@Override
public Object getItem(int position) {
//返回第position个列表项,可以用null代替
return null;
}
@Override
public long getItemId(int position) {
//返回第position项的id,一般用position代替
return position;
}
//getView方法是核心,在该方法中完全控制每一项的详细显示结果。
//本方法的最终结果是要生成一个View对象convertView,这个View对象就代表ListView的一个列表项,即第position行。
//convertView对象里面包含一个TextView对象studentName,一个ProgressBar对象progressCount,一个Button对象btnTouPiao
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
//student_toupiao_item.xml是一个布局文件,用它来生成一个View对象convertView,
// 里面定义了一个TextView对象studentName,一个ProgressBar对象progressCount,一个Button对象btnTouPiao
//LayoutInflater是一个用于加载布局的系统服务,就是用来把student_toupiao_item.xml布局文件实例化为一个View对象,
// 即将Layout xml文件创建成一个view对象。对于一个没有被载入或者想要动态载入的布局界面,都需要使用LayoutInflater.inflate()来载入;
//LayoutInflater不能直接使用,需要先获得他的实例,有三种方法:
// LayoutInflater inflater1 = LayoutInflater.from(this);
// LayoutInflater inflater2 = getLayoutInflater();
// LayoutInflater inflater3 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
convertView= LayoutInflater.from(context).inflate(R.layout.student_toupiao_item,parent,false);
TextView studentName=(TextView)convertView.findViewById(R.id.studentName);
//progressCount必须定义成final,因为在btnTouPiao.setOnClickListener方法中要用到他,否则语法通不过。
final ProgressBar progressCount=(ProgressBar)convertView.findViewById(R.id.progressCount);
Button btnTouPiao=(Button)convertView.findViewById(R.id.btnTouPiao);
//listStudent集合中第position项的学生姓名设置为TextView对象studentName的text值
studentName.setText(listStudent.get(position).getName());
//listStudent集合中第position项的学生得票数设置为ProgressBar对象progressCount的progress值
progressCount.setProgress(listStudent.get(position).getCount());
//给投票按钮btnTouPiao添加OnClickListener监听器
btnTouPiao.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//先将集合listStudent第position项的学生得票数+1
listStudent.get(position).setCount(listStudent.get(position).getCount()+1);
//再将集合listStudent第position项的学生得票数(加1后的)赋给progressCount的progress属性,让他显示出来
progressCount.setProgress(listStudent.get(position).getCount());
}
});
//返回最新变化后的convertView(即将姓名和得票数都显示到相应控件后的convertView)
return convertView;
}
}
/**Student实体类
* 包含姓名name和得票数count属性
* 一个Student对象保存一个学生的姓名和得票数,
* 将来将这些对象放到listStudent集合中,用于显示到ListView控件中。
*/
class Student{
private String name;
private int count;//该学生获得的票数
public Student(String name,int count){
this.name=name;
this.count=count;
}
public Student(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
}
BaseAdapter适配器简介:
BaseAdapter是什么:
adapter是view和数据的桥梁,而BaseAdapter就是最基础的适配器
BaseAdapter怎么用:
ListView.setAdapter(BaseAdapter)
文案内容参考:https://blog.csdn.net/Dreamhai/article/details/109705488
BaseAdapter需要继承的四个方法
public int getCount() {
//返回列表的项数
}
public Object getItem(int position) {
//返回第position个列表项,可以用null代替
}
public long getItemId(int position) {
//返回第position项的id,一般用position代替
}
public View getView(final int position, View convertView, ViewGroup parent) {
//getView方法是核心,在该方法中完全控制每一项的详细显示结果。
}
建议初学者直接跳过讲解部分,先部署一下这个案例,先将代码跑起来,出结果之后再跟着本文章的思绪去分析代码
项目部署:
直接根据各个xml以及java文件的名字放入指定的位置中,最后别忘了在AndroidManifest.xml更改对应的< intent-filter >标签