您的位置:首页 > 移动开发 > Android开发

Android适配器

2016-03-10 15:56 519 查看

一:适配器中提高性能优化如下:

1.利用convertView

利用Android的Recycler机制,利用convertView来重新回收View,效率有了本质提高。View的每次创建是比较耗时的,因此对于getview方法传入的convertView应充分利用 != null的判断 。

2.使用ViewHolder

ViewHolder将需要缓存的view封装好,convertView的setTag才是将这些缓存起来供下次调用。 当你的listview里布局多样化的时候 viewholder的作用体现明显,效率再一次提高。 View的findViewById()方法也是比较耗时的,因此需要考虑只调用一次,之后就用View.getTag()方法来获得ViewHolder对象。

3.优雅的使用ViewHolder

使用ViewHolder时,每次一遍一遍的findViewById,一遍一遍在ViewHolder里面添加View的定义,view一多,是不是感觉烦爆了,base-adapter-helper这个类库似乎完美的解决了这个问题。

万能适配器参考:http://www.2cto.com/kf/201507/414816.html

二、单独更新某一个item的数据

使listview和gridview更新数据常用的是notifyDataSetChanged,可以更新适配器的数据,但是这种方式是数据全部更新,适配数据的时候会出现闪烁的现象,但是有的时候只是想更新某一条或某部分数据,这里可以单独写一个更新数据的方法,达到只更新指定的一条item。

下面是我写的一个gridview随机更换图片的demo。listview请参考

/article/1915023.html

(1)适配器类:

public class PictureAdapter extends BaseAdapter {
private Context mContext;
private List<PictureData> mPictures;
private GridView mGridView;
public PictureAdapter(Context context, List<PictureData> pictures) {
this.mContext = context;
this.mPictures = pictures;
}
public void setPictureDatas(List<PictureData> pictures){
this.mPictures = pictures;
}
/**
* 设置gridview对象
* @param gridV
*/
public void setGridView(GridView gridV) {
this.mGridView = gridV;
}
/**
* update listview 单条数据
*
* @param item
*            新数据对象
*/
public void updateItemData(PictureData picture) {
Message msg = Message.obtain();
int ids = -1;
// 进行数据对比获取对应数据在list中的位置
for (int i = 0; i < mPictures.size(); i++) {
if (mPictures.get(i).getId() == picture.getId()) {
ids = i;
}
}
msg.arg1 = ids;
// 更新mDataList对应位置的数据
mPictures.set(ids, picture);
// handle刷新界面
han.sendMessage(msg);
}
@SuppressLint("HandlerLeak")
private Handler han = new Handler() {
public void handleMessage(android.os.Message msg) {
updateItem(msg.arg1);
};
};
/**
* 刷新指定item
*
* @param index
* item在gridview中的位置
*/
private void updateItem(int index) {
if (mGridView == null) {
return;
}
View convertView = mGridView.getChildAt(index);
// 重新设置界面显示数据
Holder holder = new Holder();
holder.img_picture = (ImageView) convertView.findViewById(R.id.img_picture);
holder.tv_picture_name = (TextView) convertView.findViewById(R.id.tv_picture_name);
holder.setView(index);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mPictures.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mPictures.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.adapter_picture_item_layout, null);
holder = new Holder();
holder.tv_picture_name = (TextView) convertView
.findViewById(R.id.tv_picture_name);
holder.img_picture = (ImageView) convertView
.findViewById(R.id.img_picture);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.setView(position);
return convertView;
}
/**
* listview 和gridview的缓存。
* @author Administrator
*
*/
class Holder {
TextView tv_picture_name;
ImageView img_picture;
public void setView(int position) {
PictureData picture = mPictures.get(position);
try {
String name = picture.getName();
int resoure = picture.getResoure();
//tv_picture_name.setText(name);
img_picture.setImageResource(resoure);
Log.i("tag", "resoure:"+resoure);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}


(2).Activity类的实现:

public class PictureActivity extends Activity implements OnClickListener {
Button bt_type;
Button bt_change;
ListView lv_picture;
GridView gv_picture;
private static final int TYPE_LIST = 1;
private static final int TYPE_GRID = TYPE_LIST + 1;
private static final int MSG_CHANGE_PICTURE = 10000;
private int type = TYPE_GRID; // 1:listview;2:gridview
private int[] pictuereDrawables = { R.drawable.header01,
R.drawable.header02, R.drawable.header03, R.drawable.header04,
R.drawable.header05, R.drawable.header06, R.drawable.header07,
R.drawable.header08, R.drawable.header09, R.drawable.header10,
R.drawable.header11, R.drawable.header12, R.drawable.header13,
R.drawable.header14, R.drawable.header15, R.drawable.header16,
R.drawable.header17, R.drawable.header18, R.drawable.header19,
R.drawable.header20, R.drawable.header21, R.drawable.header22,
R.drawable.header23 };
private List<PictureData> pictures;
private PictureAdapter mPictureAdapter;
private boolean isChanging = false;
UpdatePictureThread pictureThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adpater);
initView();
getPictureData();
mPictureAdapter = new PictureAdapter(this, pictures);
mPictureAdapter.setGridView(gv_picture);
// lv_picture.setAdapter(mPictureAdapter);
gv_picture.setAdapter(mPictureAdapter);
}
private void initView() {
bt_type = (Button) findViewById(R.id.bt_type);
bt_change = (Button) findViewById(R.id.bt_change);
lv_picture = (ListView) findViewById(R.id.lv_picture);
gv_picture = (GridView) findViewById(R.id.gv_picture);
bt_type.setOnClickListener(this);
bt_change.setOnClickListener(this);
showTypeView();
}
private void showTypeView() {
switch (type) {
case TYPE_LIST:
lv_picture.setVisibility(View.VISIBLE);
gv_picture.setVisibility(View.GONE);
break;
case TYPE_GRID:
lv_picture.setVisibility(View.GONE);
gv_picture.setVisibility(View.VISIBLE);
break;
default:
break;
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_type:
if (type == TYPE_LIST) {
type = TYPE_GRID;
} else {
type = TYPE_LIST;
}
showTypeView();
break;
case R.id.bt_change:
if (isChanging) {
stopThread();
} else {
if (pictureThread == null) {
pictureThread = new UpdatePictureThread();
}
pictureThread.start();
isChanging = true;
}
break;
default:
break;
}
}
private void getPictureData() {
pictures = new ArrayList<PictureData>();
for (int i = 0; i < pictuereDrawables.length; i++) {
PictureData picture = new PictureData();
picture.setId(1 + i);
picture.setName("person_" + (int) (i + 1));
picture.setResoure(pictuereDrawables[i]);
pictures.add(picture);
}
}
class UpdatePictureThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (isChanging) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(MSG_CHANGE_PICTURE);
}
}
}
Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CHANGE_PICTURE:
int length = pictuereDrawables.length;
Random random = new Random();
int changeIndex = random.nextInt(length);
int resoureIndex = random.nextInt(length);
if (changeIndex != resoureIndex) {
pictures.get(changeIndex).setResoure(
pictuereDrawables[resoureIndex]);
mPictureAdapter.setPictureDatas(pictures);
mPictureAdapter.updateItemData(pictures.get(changeIndex));
}
break;
default:
break;
}
};
};
private void stopThread() {
if (pictureThread != null) {
if (pictureThread.isAlive()) {
pictureThread.interrupt();
pictureThread = null;
}
}
isChanging = false;
}
}


(3)数据类的实现如下:

public class PictureData {
private int id;
private String name;
private int resoure;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getResoure() {
return resoure;
}
public void setResoure(int resoure) {
this.resoure = resoure;
}
}


(4).adapter_picture_item_layout 的实现如下:

<?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"
>
<ImageView android:id="@+id/img_picture"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:src="@drawable/header01"/>

<TextView android:id="@+id/tv_picture_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="picture_1"
android:layout_margin="5dp"
android:padding="5dp"
android:visibility="gone"
android:layout_alignParentBottom="true"/>
</RelativeLayout>


(5).activity_picture类的实现如下:

<?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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="change" />

<Button
android:id="@+id/bt_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start" />

</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<ListView
android:id="@+id/lv_picture"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
<GridView
android:id="@+id/gv_picture"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="4"
android:visibility="gone" >
</GridView>
</LinearLayout>
</LinearLayout>


三:适配器中注意事项:

1、适配器中如果添加顶部或者底部的view的时候。

setOnItemClickListener方法需要注意,可能导致添加的view占位,listview调用setOnItemClickListener的时候出现错位现象。解决这个问题可以使用回调的方式,在itemView中实现点击事件,并把响应返回给listview。

2、适配器中item如果有显示和隐藏处理

即setVisible,做出判断的时候,一定要指明是隐藏还是显示,否则或出现listview滚动的时候隐藏显示的view混乱的现象。

本文摘抄一下网站,内容更丰富,详细可阅读原文:

http://www.2cto.com/kf/201507/414816.html

/article/1915023.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: