Android 中的 ListView

在Android讲义中的示例中:

一:简单的string列表:

1,创建 String类型的ListView,通过 string [] 填充数据,或者通过string.xml创建数据;

2,在 plistview.setOnItemClickListener(newAdapterView.OnItemClickListener() 响应函数中,通过类的成员变量获取;

 
这里我简单修改一下:
ListView 是和 ArrayAdapter 配合使用的,ArrayAdapter就表示链表,ListView是容器和消息响应;
ArrayAdapter 本身就可以添加删除item:

示例:
创建:
ListView plistview = (ListView) findViewById(R.id.listView);

//item默认情况是TextView,可以直接用系统默认自带的xml文件,如:android.R.layout.simple_list_item_1;也可以参考系统的写自己的itme的xml;
ArrayAdapter<String> pArayAdapter = new ArrayAdapter<String>(this, R.layout.listview_item); 

plistview.setAdapter(pArayAdapter);

for (int i = 0; i < 100; i++) {
    pArayAdapter.add("string listview item " + i);
}

消息响应:
//通过onItemClick中的参数获取控制相关链表中的item,因为类型是创建时候定义的,所以onItemClick中的item要类型强制转换;
plistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


        String strItem = (String) parent.getItemAtPosition(position); //强制类型转换 + item获取;


        TextView pTview = (TextView)findViewById(R.id.idc_TextVIew);

        pTview.setText( strItem );
    }
});


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
关于: R.layout.listview_item ;
这里的item就是一个TextView;在XML文件中定义的TextView;
但是要注意,这个TextView的定义不可以在Layout中定义,而是在一个单独的XML文件中定义;
 
不是
<?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:weightSum="1">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/textView3"
        android:layout_weight="0.38"/>
</LinearLayout>

而是:
 
<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="107dp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Large Text"
    android:id="@+id/textView2"
    android:layout_weight="0.81"/>

 
 

在AndroidStudio中添加的话,可以直接右键添加Layout,然后在XML的Design中添加一个TextView,然后通过属性设置相关参数;
设置好后,在XML的Text中删除Layout,在相关的TextView中添加xmlns:android;


public ArrayAdapter (Context context, int resource)
Added in API level 1

Constructor

Parameters
contextThe current context.
resourceThe resource ID for a layout file containing a TextView to use when instantiating views. 




更加具体的方法可以参考帮助文档;










二:可扩展的ListView:

通常一个ListView简单显示字符串,就直接用ArrayAdapter 就可以了;

如果想在列表中显示复杂的界面,如果每一个列表项item都是一个View或多个View,那么就需要自己重写BaseAdapter了;

 ArrayAdapter就是实现了BaseAdapter可以参考:


BaseAdapter


关于BaseAdapter简单应用可以参考《Android讲义》这本书;


这里主要说一下BaseAdapter的应用;


在Android studio中可以在MainActivity类中直接通过匿名类的方法实现继承BaseAdapter类,这样可以方便的应用Context参数,就是直接用主窗口的this就可以了;

但是一般为了更好的模块化,可以右键直接创建java class,然后 extendsBaseAdapter就可以了;但是如果要用Context,可以同构造函数直接传参数,或是添加一个set函数添加;

然后通过快捷键,“Alt + Insert”,实现Implement需要实现的函数;


重要的函数有

public int getCount() :返回值表示了显示的列表数; 通过函数参数修改返回值,然后重新ListView.setAdapter重新加载显示列表控件;


public View getView(int position, View convertView, ViewGroup parent) :列表中显示View的; 
因为Android中的所有控件都是View包括Layout,所以可以返回非常复杂的列表Item;

position参数,表示当前加载的Viewd的索引序号值;



public class TestBaseAdpter extends BaseAdapter
{

    public TestBaseAdpter( Context pContext  )
    {
        m_pContext = pContext;
    }

    Context m_pContext;

    /**
     * How many items are in the data set represented by this Adapter.
     *
     * @return Count of items.
     */
    @Override
    public int getCount()
    {
        return  1000;
    }

    /**
     * Get the data item associated with the specified position in the data set.
     *
     * @param position Position of the item whose data we want within the adapter's
     *                 data set.
     * @return The data at the specified position.
     */
    @Override
    public Object getItem(int position)
    {
        return null;
    }

    /**
     * Get the row id associated with the specified position in the list.
     *
     * @param position The position of the item within the adapter's data set whose row id we want.
     * @return The id of the item at the specified position.
     */
    @Override
    public long getItemId(int position)
    {
        return 0;
    }

    /**
     * Get a View that displays the data at the specified position in the data set. You can either
     * create a View manually or inflate it from an XML layout file. When the View is inflated, the
     * parent View (GridView, ListView...) will apply default layout parameters unless you use
     * {@link LayoutInflater#inflate(int, ViewGroup, boolean)}
     * to specify a root view and to prevent attachment to the root.
     *
     * @param position    The position of the item within the adapter's data set of the item whose view
     *                    we want.
     * @param convertView The old view to reuse, if possible. Note: You should check that this view
     *                    is non-null and of an appropriate type before using. If it is not possible to convert
     *                    this view to display the correct data, this method can create a new view.
     *                    Heterogeneous lists can specify their number of view types, so that this View is
     *                    always of the right type (see {@link #getViewTypeCount()} and
     *                    {@link #getItemViewType(int)}).
     * @param parent      The parent that this view will eventually be attached to
     * @return A View corresponding to the data at the specified position.
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        TextView pView = new TextView( m_pContext );

        pView.setText( "新建字符串" );


        return  pView;
    }
}


如果要查看复杂的设计方法, 一般可以添加 List链表,返回的是List.count(), 这样就可以比较容易动态控制链表,具体可以参考Android中的ArrayAdapter;












三:用简单的方式实现ListView的扩展:

从上述实现BaseAdapter来看,有些麻烦,所以想一个简单的方法实现ListView的扩展;

还是从ArrayAdapter入手;先看帮助文档:

Class ArrayAdapter<T>

java.lang.Object

android.widget.BaseAdapter

android.widget.ArrayAdapter<T> 

从帮助文档可以看出, ArrayAdapter就是继承实现了BaseAdapter,而且,ArrayAdapter是泛型的,支持任何类型,

所以:理论上可以经任何View,任何类绑定到ArrayAdapter中;

但是ArrayAdapter本身的实现又有一些限制,ArrayAdapter构造函数接受的样式文件里只含有一个textview,然后它把接受到的数据toString后(即调用数据对象的toString方法,如果是string类型,就直接显示了;)展示在textview里。 

就是说,对于ArrayAdapter来说,不论传输什么类型的class类,最后都会显示为toString后的字符串;将字符串显示到View上;


所以:我们可以 继承 ArrayAdapter,然后修改getView函数;

我们可以参考ArrayAdapter的getView函数的实现,然后返回任何我们希望的View;



示例:

参考ArrayAdapter传入的源码,我们知道我们add的任何T类型都会被添加到里面的链表中,所以为了快速实现我们的想法,我们可以直接getView中返回链表中添加的T类型(如果是View的话,当然一般我们要显示的必然是View,所以添加的时候可以直接添加View获其子类);

//自定义类实现:

class MyArrayAdapter extends ArrayAdapter<View>
{

    public MyArrayAdapter(Context context, int resource)
    {
        super(context, resource);
    }

    public MyArrayAdapter(Context context, int resource, int textViewResourceId)
    {
        super(context, resource, textViewResourceId);
    }

    public MyArrayAdapter(Context context, int resource, View[] objects)
    {
        super(context, resource, objects);
    }

    public MyArrayAdapter(Context context, int resource, int textViewResourceId, View[] objects)
    {
        super(context, resource, textViewResourceId, objects);
    }

    public MyArrayAdapter(Context context, int resource, List<View> objects)
    {
        super(context, resource, objects);
    }

    public MyArrayAdapter(Context context, int resource, int textViewResourceId, List<View> objects)
    {
        super(context, resource, textViewResourceId, objects);
    }



    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        return getItem( position );


       // return super.getView(position, convertView, parent);
    }

}

//类应用:

MyArrayAdapterm_MyArrayAdapterButton=null;

protected void onCreate(Bundle savedInstanceState)
{
                        ...
m_MyArrayAdapterButton = new MyArrayAdapter(this, android.R.layout.simple_list_item_1 );
}
public void onClick(View v)
{   
        Button pbtn = new Button( this );
        pbtn.setText("btn: " +  m_nCount++);
        m_MyArrayAdapterButton.add( pbtn );
        listView.setAdapter( m_MyArrayAdapterButton );
}

上述示例实质返回了按钮,如果需要可以返回任何复杂的界面,当然要可以返回Layout创建的界面;








最后转两篇文章:

说明:这两篇文章应该是一个人写的,这个示例有一定的说明作用,但是这样的封装自定义类,不能很好地控制每一个item,而且会造成不确定性;

建议读者在写代码的时候尽量考虑接口的简单,类的封装,和封装的易用性,高内聚,低耦合;


http://blog.csdn.net/nairuohe/article/details/6457300

http://www.cnblogs.com/wenjiang/p/3196205.html





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chinabinlang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值