Andorid關於如何獲取listview中子item的控件的問題

Andorid 開發中咱們經常會用到listview這個控件,而listview中如何獲取到子item的控件並設置相應事件則相對複雜,而且自定義listview經常須要自定義適配器等等,下面這篇文章將主要介紹如何獲取item控件並設置響應事件,主要實現如何點擊listview子item中的一個按鈕跳轉到下一個Activity。廢話很少說直接上代碼:java

主文件:MainActivity(當前Activity)

package com.example.demo_listitem;

import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {
    private ListView list;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);    
        list=(ListView) findViewById(R.id.listView1)**//找到Listview控件**
        Cadapter ca=new Cadapter(this);**//獲得一個Cadapter對象(自定義適配器)**
        list.setAdapter(ca);**//爲listview綁定適配器**
    }
**//定義一個獲得數據的方法**
    public ArrayList<HashMap<String, Object>> getData() {
        ArrayList<HashMap<String, Object>> listitem=new 
                ArrayList<HashMap<String, Object>>();**//動態數組,裝數據**
        for(int i=0;i<20;i++)
        {
            **//利用散列映射添加簡單數據**
            HashMap<String, Object> map=new HashMap<String,Object>();
            map.put("title", "hello world");
            listitem.add(map);
        }
        return listitem;**//返回數據源**

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    
}

最重要的地方,自定義適配器:Cadatper(繼承自BaseAdapter)
(PS:使用BaseAdapter必須寫一個類繼承它,同時BaseAdapter是一個抽象類,繼承它必須實現它的方法。而最重要的方法就是getView()方法,在此方法內item的繪製(核心的核心),item內控件的尋找,事件的設定都能作。當開始繪製listview時,首先會調用其getCount()方法,獲得listview的長度,而後根據這個長度來繪製listview的每個item)android

最重要的重寫適配器:Cadapter

package com.example.demo_listitem;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView.FindListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class Cadapter extends BaseAdapter{

    private Context context1;
    private LayoutInflater mInflater;
    public Cadapter(Context context)
    {
        context1=context;**//將當前頁面的對象賦給context1**
        this.mInflater=LayoutInflater.from(context1);
    }
    @Override
    public int getCount() {
        MainActivity m=new MainActivity();
        return m.getData().size();**//返回listview長度**
        
    }

    @Override
    public Object getItem(int position) {
        return null;
    }
    
    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        
        if(convertView==null)
        {
            **//繪製子item**
            convertView=mInflater.inflate(R.layout.activity_listitem, null);
            **//獲得各個控件**
            holder=new ViewHolder();**//存放控件的對象**
            holder.tv=(TextView) convertView.findViewById(R.id.textView1);
            holder.bt=(Button) convertView.findViewById(R.id.button1);
            convertView.setTag(holder); **//將數據和convertView綁定在一塊兒**
        }
        else
        {
            holder=(ViewHolder) convertView.getTag();
        }
        MainActivity m=new MainActivity();
        holder.tv.setText(m.getData().get(position).get("title").toString());**//爲item中的Textview設置數據**
      **//按鈕的點擊事件**
        holder.bt.setOnClickListener(new View.OnClickListener() {        
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent=new Intent(context1,NextActivity.class);
                context1.startActivity(intent);
            }
        });
        return convertView;
    }
}

(getview中的代碼,其實徹底能夠不用convertView以及holder,直接加入item佈局和設計相應的組件屬性就好了,這樣作雖然行得通,但只適用於listview中item個數較少的時候可行,當item個數達到1000,10000,1000000就行不通了,由於每一個item系統都會繪製一次(getView()一次),item個數較少時還好,當大量的item須要繪製時,會耗費大量的資源在繪製上,這顯然實不可取的。
因此,以上代碼是通過優化過的,優化之處在於使用convertView和ViewHolder的使用,convertViewconvertView至關於一個緩存,當滑動時,有的條目變爲不可見,它緩存了此條目的數據,後面再出來的條目只須要更新數據就能夠了,這樣大大節省了系統資料的開銷
而ViewHolder也是對listview的進一步優化,將holder(找到的控件)用setTag綁定到convertView上,用的時候再用getTag()取出,不用每次都去findviewById,節約系統開銷)web

下一個頁面的Activity:NextActivity

package com.example.deo_listitem;
import android.app.Activity;
import android.os.Bundle;
public class NextActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next);
    }
}

ViewHolder:

package com.example.demo_listitem;

import android.widget.Button;
import android.widget.TextView;

public final class ViewHolder {
    public TextView tv;
    public Button bt;
}

listvew佈局文件:activity_listview

<?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" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

子item佈局文件:activity_listitem(就一個textview和一個button)

<?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"
    android:weightSum="1" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="vertical"
        android:background="#ddc200"
        android:weightSum="1" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="vertical"
            android:layout_weight="0.5" >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Medium Text"
                android:textAppearance="?android:attr/textAppearanceMedium" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.5"
            android:orientation="vertical" >

            <Button
                android:id="@+id/button1"
                style="?android:attr/buttonStyleSmall"
                android:layout_width="112dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="下一頁" />
        </LinearLayout>

    </LinearLayout>

</LinearLayout>

下一個頁面的佈局文件:activity_next

<?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"
    android:background="#ddc200" >
</LinearLayout>

convertView原理:當初始顯示一屏listview時,convertView的值爲空,(由於沒有舊的item,舊的指:滑動時移出屏幕的item),當屏幕移動時,有的item滑到屏幕外面,成了舊的item,convertView會回收這些成爲舊了的item並緩存起來,若是有新的item產生,則getview()中的convertView就不是空的,而是移出屏幕的item的值(舊item),咱們須要作的就是將須要顯示的數據填充進去就好了,也就是說convertView至關於一個緩存,當有條目變爲不可見,它緩存了它的數據,後面再出來的條目只須要更新數據就能夠了,這樣大大節省了系統資料的開銷。數組

相關文章
相關標籤/搜索