Fruit实体类
package com.example.entity;
/*
* 实体类给ListView提供数据
*/
public class Fruit {
int imageId;
String name;
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
fruit_listview.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/fruitImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</ImageView>
<TextView
android:id="@+id/fruitText"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
FruitAdapter
package com.example.adapter;
import java.util.List;
import com.example.entity.Fruit;
import com.example.testsometing.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class FruitAdapter extends ArrayAdapter<Fruit>{
int resourceId;
public FruitAdapter(Context context, int resource, List<Fruit> fruitList) {
super(context, resource, fruitList);
resourceId=resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view=LayoutInflater.from(getContext()).inflate(resourceId,null);
ImageView fruitImage =(ImageView) view.findViewById(R.id.fruitImage);
TextView fruitText =(TextView) view.findViewById(R.id.fruitText);
Fruit fruit =getItem(position);
fruitImage.setImageResource(fruit.getImageId());
fruitText.setText(fruit.getName());
return view;
}
}
MainActivity
List<Fruit> fruitList ;
{
initFruitList();
ListView listview =(ListView) this.findViewById(R.id.listview);
FruitAdapter fruitAdapter =new FruitAdapter(this, R.layout.fruit_listviewx, fruitList);
listview.setAdapter(fruitAdapter);
}
//初始化FruitList
private void initFruitList(){
fruitList = new ArrayList<Fruit>();
Fruit fruit1 =new Fruit();
fruit1.setImageId(R.drawable.ic_launcher);
fruit1.setName("1");
fruitList.add(fruit1);
Fruit fruit2 =new Fruit();
fruit2.setImageId(R.drawable.ic_launcher);
fruit2.setName("2");
fruitList.add(fruit2);
}
优化listview
1.使用converView,convertView是对加载好的布局进行缓存
2.使用ViewHolder
public class ViewHolder {
ImageView fruitImage;
TextView fruitText;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
viewHolder =new ViewHolder();
viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruitImage);
viewHolder.fruitText = (TextView) view.findViewById(R.id.fruitText);
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
Fruit fruit = getItem(position);
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitText.setText(fruit.getName());
return view;
}
2016/01/14
体会:
(1). ListView一开始只会加载可见的item数,即如果只可以看见11条item,就会按顺序调用11次getView();这个操作会调用4次,即加载完第11个item后会重新加载第一个item,如此循环4次。
(2). 当下滑时,会陆续调用getView()来显示那些item;
(3). 当上滑时,还会继续调用getView(),即已经出现过的item,当上滑时也会重新调用getView()来显示;
(4). adapter.notifydatasetchange();会调用当前可视最大的item数量的getView(),比如下滑到第17个item,此时getView()会被调用,position从1~17(有的getView(position)会被调用2次(为中间的几个position,这个也不知道为什么)),而不会调用getView()里position为17之后的。
2016/2/06更新
自定义listview实现下拉刷新(粗糙之作,不适合正式使用)
效果:
MyListView
package com.example.day0205;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MyListView extends ListView implements OnScrollListener{
private View header;
private int headerHeight;
private int firstVisibleItem;
private int scrollState;
private int mStartY;
private boolean isRemark;//标记,当前是在listvw最顶端按下的
private int state;
private final int NORMAL = 0;//正常涨停,遮蔽header
private final int PULL = 1;//提示可以下拉刷新
private final int RELEASE = 2;//提示松开可以刷新
private final int REFLASHING = 3;//正在刷新
private TextView tip1;
private TextView tip2;
private ImageView iv_tip;
private ReflashInterface reflashInterface;
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
header = inflater.inflate(R.layout.layout_header, null);
tip1 = (TextView) header.findViewById(R.id.textView1);
tip2 = (TextView) header.findViewById(R.id.textView2);
iv_tip = (ImageView) header.findViewById(R.id.imageView1);
header.measure(0, 0);//让view measure(w,h)一下,getMeasuredHeight()才不为0,但getMeasuredHeight的值与w,h无关
headerHeight = header.getMeasuredHeight();
hideHeader();
this.addHeaderView(header);
//不set的话没有效果
this.setOnScrollListener(this);
}
private void hideHeader() {
// MeasureView(header);
// headerHeight = header.getMeasuredHeight(); 不能每次都测量,因为在下拉过程中header显示的不全,因此显示的也不全
Log.v("TAG", "hide"+headerHeight +": "+state);
header.setPadding(header.getPaddingLeft(), -headerHeight, header.getPaddingRight(), header.getPaddingBottom());
}
/**
* 通知父布局自己的宽, 高
* @param view
*/
private void MeasureView(View view) {
ViewGroup.LayoutParams p = view.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int height;
int tempHeight = p.height;
if (tempHeight>0) {
height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
} else {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(width, height);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.scrollState = scrollState;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.firstVisibleItem = firstVisibleItem;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleItem == 0) {
isRemark = true;
mStartY = (int) ev.getY();
} else {
isRemark = false;
}
break;
case MotionEvent.ACTION_MOVE :
onMove(ev);
break;
case MotionEvent.ACTION_UP :
if (state == RELEASE) {
state = REFLASHING;
reflashInterface.reflash();//耗时操作
reflashViewByState();
} else if (state == PULL){
state = NORMAL;
isRemark = false;
reflashViewByState();
Log.v("TAG", "up");
}
break;
}
return super.onTouchEvent(ev);
}
private void onMove(MotionEvent ev) {
if (!isRemark) {
return;
}
int tempY = (int) ev.getY();
int space = tempY - mStartY;
switch (state) {
case NORMAL:
if (space > 0) {
state = PULL;
}
break;
case PULL:
showHeader(space-headerHeight);
if (space > headerHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL) {
state = RELEASE;
}
Log.v("TAG", state+"-->");
reflashViewByState();
break;
case RELEASE:
if (space < headerHeight + 30) {
state = PULL;
}
Log.v("TAG", state+"-->"+space + " , "+(headerHeight + 30));
reflashViewByState();
break;
}
}
/**
* 根据状态改变显示
*/
private void reflashViewByState() {
switch (state) {
case NORMAL:
hideHeader();
break;
case PULL:
tip1.setText("下拉可以刷新");
break;
case RELEASE:
tip1.setText("释放可以刷新");
break;
case REFLASHING:
tip1.setText("正在刷新");
RotateAnimation animation = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F);
animation.setDuration(2000);
animation.setRepeatCount(3);
iv_tip.startAnimation(animation);
break;
}
}
private void showHeader(int f) {
Log.v("TAG", "show"+f);
header.setPadding(header.getPaddingLeft(), (int) f, header.getPaddingRight(), header.getPaddingBottom());
}
public void getDataComplete(){
state = NORMAL;
reflashViewByState();
}
public interface ReflashInterface {
public void reflash();
}
public void setReFlashInterface(ReflashInterface reflashInterface) {
this.reflashInterface = reflashInterface;
}
}
layout_header.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="90dp"
android:layout_marginTop="17dp"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="下拉可以刷新" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="上次更新数据" />
</LinearLayout>
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/linearLayout1"
android:layout_marginRight="20dp"
android:layout_toLeftOf="@+id/linearLayout1"
android:src="@drawable/ic_launcher" />
</RelativeLayout>
MainActivity
package com.example.day0205;
import com.example.day0205.MyListView.ReflashInterface;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class SecondActivity extends Activity implements ReflashInterface{
private MyListView listView;
private ArrayAdapter<String> adapter;
private volatile String[] data ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
listView = (MyListView) findViewById(R.id.listView1);
data = new String[100];
for (int i = 0;i<data.length;i++) {
data[i] = 100-i+"";
}
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);
listView.setReFlashInterface(this);
listView.setAdapter(adapter);
}
@Override
public void reflash() {
//耗时操作
//模拟
getNewData();
}
protected void getNewData() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0;i<data.length;i++) {
data[i] = (i+"=new");
}
adapter.notifyDataSetChanged();
listView.getDataComplete();
}
}, 3000);
}
}