最近在研究如何自訂listView,在網路上看了相關的文件
所以就來玩看看
一般來說一個最簡單的ListView是長這樣
如果利用內建SampleAdapter就大概會是這樣
那如果要放圖或者checkbox、Button等呢
那麼就利用BaseAdapter來就可以辦到了
那麼就利用BaseAdapter來就可以辦到了
步驟:
我的例子是利用spinner來選取listview,並用BaseAdapter來建立自己的listview
create spinner就不說了
create spinner就不說了
public class HelloList extends Activity{
private Spinner sp1;
private ArrayAdapter<String> adapter1;
private ArrayList<String> lstSpinner = new ArrayList<String>();
private MyListViewAdapter base;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
init();
}
private void init()
{
lv = (ListView)findViewById(R.id.activity_list_listView1);
sp1 = (Spinner) findViewById(R.id.login_spinner1);
lst1= new ArrayList<String>();
lst1.add("Hank");
lst1.add("Lin");
lst1.add("Paul");
lstSpinner.add("ListView Type 1");
lstSpinner.add("ListView Type 2");
lstSpinner.add("ListView Type 3");
lstSpinner.add("ListView Type 4");
adapter1 = new ArrayAdapter<String>(HelloList.this, android.R.layout.simple_spinner_item, lstSpinner);
sp1.setAdapter(adapter1);
sp1.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> aparent, View view, int position, long id) {
// TODO Auto-generated method stub
switch(position){
case 0:
base =new MyListViewAdapter(HelloList.this, lst3) ;
lv.setAdapter(base);
break;
}
}
});
}
}
再來看看自訂的baseAdapter
- 首先create 你的Adapater然後extands BaseAdapter 你會需要Override 4個methods
- View getView(int position, View convertView, ViewGroup parent):修改View的內容
- int getCount() : 取得listview有多少列
- Object getItem(int position):取得某一列的內容
- long getItemId(int position):取得某一列的ID
- 建立一個class ViewTag去存取它的屬性
- 在getView裡面去讀取ViewTag和設定對應元件
public class MyListViewAdapter extends BaseAdapter
{
Context context;
ArrayList<HashMap<String, Object>> lst;
LayoutInflater inflater;
private Handler viewtaganimation= new Handler();//icon動畫
public MyListViewAdapter(Context ctx, ArrayList<HashMap<String, Object>> l)
{
super();
// TODO Auto-generated constructor stub
this.context = ctx;
this.lst = l;
inflater = LayoutInflater.from(ctx);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewTag viewTag;
viewtaganimation= new Handler();
if(convertView == null){
convertView = inflater.inflate(R.layout.simple_list_item_3,null);//實體化view
viewTag = new ViewTag(
(ImageView)convertView.findViewById(R.id.simple_list_item_3_imageView1),
(TextView)convertView.findViewById(R.id.simple_list_item_3_textView1),
(TextView)convertView.findViewById(R.id.simple_list_item_3_textView2),
(AnimationDrawable) context.getResources().getDrawable(R.anim.animation2));
convertView.setTag(viewTag); //绑定ViewTag對象
}
else{
viewTag = (ViewTag) convertView.getTag();
}
//設定元件
viewTag.tv1.setText(lst.get(position).get("item1").toString());
viewTag.tv2.setText(lst.get(position).get("item2").toString());
viewTag.icon.setImageDrawable(viewTag.ad);
//animation
viewtaganimation.postDelayed(new MyRunnable(viewTag.ad,viewTag.icon),200);
return convertView;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return lst.size(); //共有幾列
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
//宣告成一個類別讓該列屬性去讀取
class ViewTag{
ImageView icon;
TextView tv1,tv2;
AnimationDrawable ad;
public ViewTag(ImageView icon, TextView tv1, TextView tv2, AnimationDrawable ad){
this.icon = icon;
this.tv1 = tv1;
this.tv2 = tv2;
this.ad=ad;
}
}
private class MyRunnable implements Runnable
{
private AnimationDrawable a;
private ImageView k;
public MyRunnable(AnimationDrawable a, ImageView k)
{
this.a = a;
this.k=k;
}
@Override
public void run()
{
this.a.start();
this.k.invalidate();
}
}
}
執行結果:
在這裡我做了一個icon動畫,只要程式進去自動會跑annimation icon
步驟如下:
- 在BaseAdapter中宣告一個私有類別成員 private Handler viewtaganimation= new Handler();
- 在GetView裡面new一個Handler
- 宣告要一個class MyRunnable去實作Runnable
- 最後viewtaganimation.postDelayed(new MyRunnable(viewTag.ad, viewTag.icon), 200);
issue
這邊遇到問題是:在模擬器上面執行動畫沒問題,但是跑在手機上面卻不會執行
所以就在Run裡加了這行
所以就在Run裡加了這行
this.k.invalidate();invalidate
invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。Here
詢問過老師後他給我的解答是:
手機大都有客製的Launcher, 當View改變要自己通知自己invalidate,否則會focus在各家客製手機的Launcher上
摁,還是有點不太懂
手機大都有客製的Launcher, 當View改變要自己通知自己invalidate,否則會focus在各家客製手機的Launcher上
摁,還是有點不太懂
沒有留言:
張貼留言