一、列表视图ListView
1、ListView允许在页面上分行展示数据列表,例如新闻列表、商品列表等,方便用户浏览与操作
2、ListView去掉分隔线
设置属性:
android:divider="@null"
android:dividerHeight="0dp"
3、ListView去掉点击的动画效果
设置属性:
android:listSelector="#00000000"
4、例子
ListViewActivity.java
java
package com.example.chapter08;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import com.example.chapter08.adapter.PlanetBaseAdapter;
import com.example.chapter08.bean.Planet;
import com.example.chapter08.util.ImageUtil;
import com.example.chapter08.util.ToastUtil;
import java.util.List;
public class ListViewActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, CompoundButton.OnCheckedChangeListener {
private List<Planet> planetList;
private CheckBox ck_divider;
private CheckBox ck_selector;
private ListView lv_planet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
lv_planet = findViewById(R.id.lv_planet);
planetList = Planet.getDefaultList();
PlanetBaseAdapter adapter = new PlanetBaseAdapter(this, planetList);
lv_planet.setAdapter(adapter);
lv_planet.setOnItemClickListener(this);
ck_divider = findViewById(R.id.ck_divider);
ck_selector = findViewById(R.id.ck_selector);
ck_divider.setOnCheckedChangeListener(this);
ck_selector.setOnCheckedChangeListener(this);
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
ToastUtil.show(this, "您选择的是:" + planetList.get(position).getName());
}
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (compoundButton.getId() == R.id.ck_divider) {
// 显示分隔线
if (ck_divider.isChecked()) {
Drawable drawable = getResources().getDrawable(R.color.black, getTheme());
lv_planet.setDivider(drawable);
// 设置分隔线的高度
lv_planet.setDividerHeight(ImageUtil.dip2px(this, 1));
} else {
lv_planet.setDivider(null);
lv_planet.setDividerHeight(0);
}
} else if (compoundButton.getId() == R.id.ck_selector) {
if (ck_selector.isChecked()) {
// 显示按压背景
lv_planet.setSelector(R.drawable.list_selector); // 设置选择器
} else {
Drawable drawable = getResources().getDrawable(R.color.transparent, getTheme());
lv_planet.setSelector(drawable);
}
}
}
}
布局文件activity_list_view.xml
java
<?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"
android:orientation="vertical"
tools:context=".ListViewActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<CheckBox
android:id="@+id/ck_divider"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start|center"
android:text="显示分隔线"
android:textSize="17sp"/>
<CheckBox
android:id="@+id/ck_selector"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start|center"
android:text="显示按压背景"
android:textSize="17sp"/>
</LinearLayout>
<ListView
android:id="@+id/lv_planet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
android:dividerHeight="0dp"
android:listSelector="@color/transparent"
/>
</LinearLayout>
适配器PlanetBaseAdapter.java
java
package com.example.chapter08.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.chapter08.R;
import com.example.chapter08.bean.Planet;
import java.util.List;
public class PlanetBaseAdapter extends BaseAdapter {
private Context mContext;
private List<Planet> mPlanetList;
public PlanetBaseAdapter(Context mContext, List<Planet> mPlanetList) {
this.mContext = mContext;
this.mPlanetList = mPlanetList;
}
// 获取列表项的个数
@Override
public int getCount() {
return mPlanetList.size();
}
// 获取第i个条目
@Override
public Object getItem(int i) {
return mPlanetList.get(i);
}
// 获取item的id,没有id则返回下标
@Override
public long getItemId(int i) {
return i;
}
// 获取列表条目的View对象,这样才能显示出来
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
// 根据布局文件item_list.xml生成转换视图对象
// 布局加载器
view = LayoutInflater.from(mContext).inflate(R.layout.item_list, null);
holder = new ViewHolder();
holder.iv_icon = view.findViewById(R.id.iv_icon);
holder.tv_name = view.findViewById(R.id.tv_name);
holder.tv_desc = view.findViewById(R.id.tv_desc);
// 把holder绑定到View上
view.setTag(holder); // 将视图持有者保存到转换视图当中
} else {
holder = (ViewHolder) view.getTag();
}
// 给控件设置好数据
Planet planet = mPlanetList.get(i);
holder.iv_icon.setImageResource(planet.getImage());
holder.tv_name.setText(planet.getName());
holder.tv_desc.setText(planet.getDesc());
return view;
}
// 把控件打包,放入convertView中
public final class ViewHolder {
public ImageView iv_icon;
public TextView tv_name;
public TextView tv_desc;
}
}
条目文件item_list.xml
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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 显示行星图片的图像视图 -->
<ImageView
android:id="@+id/iv_icon"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:scaleType="fitCenter"
tools:src="@drawable/shuixing"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical"
android:layout_marginStart="5dp">
<!-- 显示行星名称的文本视图 -->
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="start|center"
android:textColor="@color/black"
android:textSize="17sp"
tools:text="水星"/>
<!-- 显示行星描述的文本视图 -->
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="start|center"
android:textColor="@color/black"
android:textSize="13sp"
tools:text="水星是太阳系八大行星之一"/>
</LinearLayout>
</LinearLayout>
选择器list_selector.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/orange"/>
<item android:drawable="@color/white"/>
</selector>
颜色资源colors.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="orange">#FFFFDD</color>
<color name="transparent">#00000000</color>
</resources>
二、Android事件传递机制
1、如果在ListView的条目里有个按钮,此时点击条目会没有反应
一般来说事件会向下传递
2、在条目的xml文件中设置android:descendantFocusability="blocksDescendants"
blocksDescendants可阻止下级控件获得焦点,避免堵塞列表视图的点击事件
或者在代码中也可以设置
3、例子
ListFocusActivity.java
java
package com.example.chapter08;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import com.example.chapter08.adapter.PlanetListWithButtonAdapter;
import com.example.chapter08.bean.Planet;
import com.example.chapter08.util.ToastUtil;
import java.util.List;
public class ListFocusActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private List<Planet> planetList;
private ListView lv_planet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_focus);
lv_planet = findViewById(R.id.lv_planet);
planetList = Planet.getDefaultList();
PlanetListWithButtonAdapter adapter = new PlanetListWithButtonAdapter(this, planetList);
lv_planet.setAdapter(adapter);
lv_planet.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
ToastUtil.show(this, "条目被点击了:" + planetList.get(position).getName());
}
}
布局文件activity_list_focus.xml
XML
<?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"
android:orientation="vertical"
tools:context=".ListFocusActivity">
<ListView
android:id="@+id/lv_planet"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
适配器PlanetListWithButtonAdapter.java
java
package com.example.chapter08.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.chapter08.R;
import com.example.chapter08.bean.Planet;
import com.example.chapter08.util.ToastUtil;
import java.util.List;
public class PlanetListWithButtonAdapter extends BaseAdapter {
private Context mContext;
private List<Planet> mPlanetList;
public PlanetListWithButtonAdapter(Context mContext, List<Planet> mPlanetList) {
this.mContext = mContext;
this.mPlanetList = mPlanetList;
}
// 获取列表项的个数
@Override
public int getCount() {
return mPlanetList.size();
}
// 获取第i个条目
@Override
public Object getItem(int i) {
return mPlanetList.get(i);
}
// 获取item的id,没有id则返回下标
@Override
public long getItemId(int i) {
return i;
}
// 获取列表条目的View对象,这样才能显示出来
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
// 根据布局文件item_list.xml生成转换视图对象
// 布局加载器
view = LayoutInflater.from(mContext).inflate(R.layout.item_list_with_button, null);
holder = new ViewHolder();
holder.ll_item = view.findViewById(R.id.ll_item);
holder.iv_icon = view.findViewById(R.id.iv_icon);
holder.tv_name = view.findViewById(R.id.tv_name);
holder.tv_desc = view.findViewById(R.id.tv_desc);
holder.btn_oper = view.findViewById(R.id.btn_oper);
// 把holder绑定到View上
view.setTag(holder); // 将视图持有者保存到转换视图当中
} else {
holder = (ViewHolder) view.getTag();
}
// 给控件设置好数据
Planet planet = mPlanetList.get(i);
holder.ll_item.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
holder.iv_icon.setImageResource(planet.getImage());
holder.tv_name.setText(planet.getName());
holder.tv_desc.setText(planet.getDesc());
holder.btn_oper.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ToastUtil.show(mContext, "按钮被点击了:" + planet.getName());
}
});
return view;
}
// 把控件打包,放入convertView中
public final class ViewHolder {
public LinearLayout ll_item;
public ImageView iv_icon;
public TextView tv_name;
public TextView tv_desc;
public Button btn_oper;
}
}
条目文件item_list_with_button.xml
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:id="@+id/ll_item"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 显示行星图片的图像视图 -->
<ImageView
android:id="@+id/iv_icon"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:scaleType="fitCenter"
tools:src="@drawable/shuixing"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical"
android:layout_marginStart="5dp">
<!-- 显示行星名称的文本视图 -->
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="start|center"
android:textColor="@color/black"
android:textSize="17sp"
tools:text="水星"/>
<!-- 显示行星描述的文本视图 -->
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="start|center"
android:textColor="@color/black"
android:textSize="13sp"
tools:text="水星是太阳系八大行星之一"/>
</LinearLayout>
<Button
android:id="@+id/btn_oper"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="点我"
android:gravity="center"/>
</LinearLayout>