ListView之手动的简单老虎机
如何使用listview:
第一步:在布局文件总声明ListView
<ListView android:id="@+id/lv" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> <ListView android:id="@+id/lv2" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> <ListView android:id="@+id/lv3" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView>
- 第二步:在*activity.java中找到ListView
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
//[找到此ListView]
ListView viewById = (ListView) findViewById(R.id.lv);
ListView viewById2 = (ListView) findViewById(R.id.lv2);
ListView viewById3 = (ListView) findViewById(R.id.lv3);
}
- 第三步:创建adapter
//创建Adapter
class TigerAdapter extends BaseAdapter {
//共有多少条目
@Override
public int getCount() {
return 10;
}
//获取条目
@Override
public Object getItem(int position) {
return position;
}
//获取条目id
@Override
public long getItemId(int position) {
return position;
}
//获取一个view ,显示的item
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = null;
if (convertView == null) {
Log.d("benny", "我是新建的listview哦" + position);
tv = new TextView(MainActivity.this);
} else {
Log.d("benny", "我是复用的listview哦" + position);
//复用listview 不用每次去创建,启动优化作用
tv = (TextView) convertView;
}
int newposition = position % 3;
if (newposition == 0) {
tv.setText("香蕉");
tv.setTextColor(Color.YELLOW);
}
if (newposition == 1) {
tv.setText("苹果");
tv.setTextColor(Color.RED);
}
if (newposition == 2) {
tv.setText("西瓜");
tv.setTextColor(Color.GREEN);
}
tv.setTextSize(12);
return tv;
}
}
- 第四步:将listview与adapter绑定
//[将listview与adapter绑定,注意此处传入的是一个 *.java 要 new 出一个对象]
viewById.setAdapter(new TigerAdapter());
viewById2.setAdapter(new TigerAdapter());
viewById3.setAdapter(new TigerAdapter());
//可以设置默认选中哪一个位置
viewById.setSelection(14);
viewById2.setSelection(17);
viewById3.setSelection(33);
运行效果:
复杂版ListView
- 新建item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<ImageView
android:id="@+id/img"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="@drawable/muer14" />
<TextView
android:id="@+id/txt_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/img"
android:singleLine="true"
android:text="王菲谢霆锋进入宾馆四天没有出来王菲谢霆锋进入宾馆四天没有出来"
android:textColor="#020202"/>
<TextView
android:id="@+id/txt_content"
android:layout_toRightOf="@+id/img"
android:layout_below="@+id/txt_title"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="如果有一天,你没有了我,多年以后你是否还会记得我们当年一起开心的日子。"
android:textColor="#898888"/>
<TextView
android:id="@+id/txt_btn"
android:layout_below="@+id/txt_content"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#ff0000"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="专题" />
</RelativeLayout>
- 创建adapter
//创建Adapter
class NewsAdapter extends BaseAdapter {
//共有多少条目
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
//获取条目
@Override
public Object getItem(int position) {
return getItem(position);
}
//获取条目id
@Override
public long getItemId(int position) {
return position;
}
//获取一个view ,显示的item
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (view == null) {
/**
* context 上下文路径 MainActivity.this
* resource 布局文件id
*
*/
view = View.inflate(MainActivity.this, R.layout.items, null);
} else {
view = convertView;
}
TextView viewById = (TextView) view.findViewById(R.id.txt_btn);
if (position == 0) {
viewById.setText("专题");
viewById.setTextColor(Color.RED);
} else {
int v = (int) (Math.random() * 10 + 10);
viewById.setText(v + "跟帖数");
viewById.setTextColor(Color.DKGRAY);
}
return view;
}
}
- 第三步:在*activity.java中找到ListView并绑定adapter
//[找到ListView]
ListView viewById = (ListView) findViewById(R.id.lv);
//[将listview与adapter绑定,注意此处传入的是一个 *.java 要new]
viewById.setAdapter(new NewsAdapter());
运行效果:
复杂的adapter
- inflate的三种方式:
//1、第一种
View view = View.inflate(MainActivity.this, R.layout.items, null);
//2、第二种
LayoutInflater factory = LayoutInflater.from(MainActivity.this);
View view = factory.inflate(R.layout.items, null);
//3、第三种
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.items, null);
// 以上三种是一模一样的 只不过,
// 第一种方法里面调用了第二种,
// 第二种里面调用了第三种
//*谷歌工程师们使用的是第三种*
其他常用Adapter
- ArrayAdapter
多用于显示简单列表:例如这种情况
布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
//[找到ListView]
ListView viewById = (ListView) findViewById(R.id.lv);
//[将listview与adapter绑定,new 一个arrayAdapter]
String[] data = {"如果","有一天","我可以自己选择","那该多好"};
String[] arrs = new String[100];
for (int i = 0; i <100 ; i++) {
arrs[i] = data[i%4]+i;
}
viewById.setAdapter(new ArrayAdapter<String>(this, R.layout.arritems,R.id.txt,arrs));
}
- SimpleAdapter
simpleAdapter适用的情况:
布局文件:simpleItem.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txt"
android:textSize="20dp"
android:textColor="@color/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/num"
android:layout_below="@+id/txt"
android:textColor="@color/colorPrimaryDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
MainActivity中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
//[找到ListView]
ListView viewById = (ListView) findViewById(R.id.lv);
List list = new ArrayList();
Map<String, String> map = null;
for (int i = 0; i < 200; i++) {
map = new HashMap<String, String>();
map.put("name", "哆啦A梦" + i);
map.put("age", "20" + i);
list.add(map);
}
viewById.setAdapter(new SimpleAdapter(this, list, R.layout.simpleitems, new String[]{"name", "age"}, new int[]{R.id.txt, R.id.num}));
}
ArrayAdapter和SimpleAdapter都是集成了BaseAdapter,只不过是谷歌为我们封装了一下,实际上仍然是BaseAdapter。
那些关于ListView的事:
- 关于ViewGroup:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
}
以上代码与以下代码是一样的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(this, R.layout.items, null);
setContentView(view);
此处有一个问题:inflate()方法中最后一个参数是VIewGroup,我们一般大多数通常都传的是一个null,为什么呢?
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.nsv);
View view = View.inflate(this, R.layout.items, linearLayout);
}
原因是:此处需要传递的是一个ViewGroup,那么ViewGroup究竟是谁呢?
@RemoteView
public class LinearLayout extends ViewGroup {...}
---------------------------------------------------
@RemoteView
public class FrameLayout extends ViewGroup {...}
---------------------------------------------------
@RemoteView
public class RelativeLayout extends ViewGroup {...}
现在你知道谁是ViewGroup了吧,因为绝大多数情况下,我们只会通过findViewById(R.id.???)去操作一个组件不会去操作findViewById(R.id.linearlayout)去操作一个线性布局。
- 关于优化:
不好的方式:Bad
<ListView
android:id="@+id/lv"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
好的方式:Good
<ListView
android:id="@+id/lv"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
截图说明二者之间的区别:
- 第一种是使用wrap_parent方式: 共输出了4次,猜测原因可能是: 因为是wrap 适应,所以第一遍的时候先测量宽度,第二遍的时候测量高度,第三遍输出一遍看是否铺满屏幕,最后输出当前要显示的内容。
- 第二种是使用fill_parent方式:因为此种方式已经知道自己的高度和宽度所以不需要测量故只输出了一次。
根据以上内容可以得知:如果当显示的ListView中的内容很多的时候,如果使用wrap方式,会占用大量资源,会造成卡顿。
——————————更新时间 2016年3月22日 晚0.25分
错误
- 布局文件错误
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: FATAL EXCEPTION: main
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: Process: com.example.administrator.studytest2, PID: 11714
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2
E/AndroidRuntime: java.lang.UnsupportedOperationException: Can't convert to dimension: type=0x12
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.content.res.TypedArray.getDimensionPixelSize(TypedArray.java:572)
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:6660)
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.widget.RelativeLayout$LayoutParams.<init>(RelativeLayout.java:1243)
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:1083)
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:82)
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:808)
03-22 10:18:40.513 11714-11714/com.example.administrator.studytest2 E/AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:504)