建立自己的TextView和ImageView的组合View类

简介:

http://www.cnblogs.com/hibraincol/archive/2010/09/25/1834869.html


在编写Android应用程序时,很多时候都需要自己来扩张Android的view类。 这里介绍一个最基本的扩展View类:利用TextView和ImageView组合成我们自己的IconTextView类。

 

第一步:我们必须先创建一个包含了有String mText 和 Drawable mIcon数据成员的类,并且该类中应包含有对这两个数据成员进行Set和Get的成员函数。

package hi.braincol.local.filebrowser.icontextlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.graphics.drawable.Drawable;
//IconText类,该类中主要有两个数据成员:String mText 和 Drawable mIcon。
//并实现了泛型接口Comparable<?>,实现这个接口的目的是为了
//让类似于"List<IconText> Entries = new ArrayList<IconText>();"
//的对象Entries具有排序功能"Collections.sort(Entries);"
public class IconText implements Comparable<IconText>{
    private String mText = " ";
    private Drawable mIcon;
    private boolean mSelectable = true;
    public IconifiedText(String text, Drawable bullet) {
        mIcon = bullet;
        mText = text;
    }
    public boolean isSelectable() {
        return mSelectable;
    }
    public void setSelectable(boolean selectable) {
        mSelectable = selectable;
    }
    //获取Text
    public String getText() {
        return mText;
    }
    //设置Text
    public void setText(String text) {
        mText = text;
    }
    //获取Icon
    public void setIcon(Drawable icon) {
        mIcon = icon;
    }
    //设置Icon
    public Drawable getIcon() {
        return mIcon;
    }
    //Comparable<?>接口中的方法
    @Override
    public int compareTo(IconText other) {
        if(this.mText != null)
            return this.mText.compareTo(other.getText()); 
        else 
            throw new IllegalArgumentException();
    }
}

第二步:创建一个TextView和ImageView组合成的View子类.

package hi.braincol.local.filebrowser.icontextlist;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
//创建一个text和Icon组合的view子类
//继承与LinerLayout表示两个IconTextView中的TextView和ImageView之间是线性布局关系。
public class IconTextView extends LinearLayout {
    //类中的两个私有成员,Text和Icon
    //IconifiedTextView中的两个子View。由TextView和ImageView组合成一个新的View。
    private TextView mText;
    private ImageView mIcon;
    public IconifiedTextView(Context context, IconText aIconText) {
        super(context);
        /* First Icon and the Text to the right (horizontal),
         * not above and below (vertical) */
        //设置IconifiedTextView为水平线性布局
        this.setOrientation(HORIZONTAL);
        //垂直居中对齐
        this.setGravity(Gravity.CENTER_VERTICAL);
        //添加ImageView
        mIcon = new ImageView(context);
        mIcon.setImageDrawable(aIconText.getIcon());
        // left, top, right, bottom
        mIcon.setPadding(0, 2, 5, 2); // 5px to the right
        /* At first, add the Icon to ourself
         * (! we are extending LinearLayout) */
        addView(mIcon,  new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
        //添加TextView, 由于先添加ImageView后添加TextView,所以 ICON 在前 Text 在后。
        mText = new TextView(context);
        mText.setText(aIconText.getText());
        /* Now the text (after the icon) */
        mText.setTextSize(17);
        mText.setPadding(5,2,2,0);
        //mText.setGravity(CENTER_VERTICAL);
        addView(mText, new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    }
    //设置TextView的Text内容
    public void setText(String words) {
        //Log.i("test","setText  "+words);
        mText.setText(words);
    }
    //设置ImageView的Icon图标
    public void setIcon(Drawable bullet) {
        //Log.i("test","setIcon  ");
        mIcon.setImageDrawable(bullet);
    }
}

第三步:建立一个BaseAdapter的子类用于Activity的布局(显示),也就是将很多IconTextView组合在一起。

package hi.braincol.local.filebrowser.icontextlist;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
//创建一个由IconText组成的ListAdapter。
public class IconTextListAdapter extends BaseAdapter {
    /** Remember our context so we can use it when constructing views. */
    private Context mContext;
    //创建一个数组适配器,适配器中每个元素为IconText
    private List<IconText> mItems = new ArrayList<IconText>();
    public IconTextListAdapter(Context context) {
        mContext = context;
    }
    //向适配器内增加元素
    public void addItem(IconText it) { mItems.add(it); }
    //设置适配器
    public void setListItems(List<IconText> lit) { mItems = lit; }
    /** @return The number of items in the List<IconText> mItems*/
    public int getCount() { return mItems.size(); }
    //获取positon指定位置的IconifiedText元素
    public Object getItem(int position) { return mItems.get(position); }
    public boolean areAllItemsSelectable() { return false; }
    //判断适配器内某个元素是否被选中
    public boolean isSelectable(int position) { 
        //Log.i("braincol","isSelectable");
        return mItems.get(position).isSelectable();
    }
    /** Use the array index as a unique id. */
    public long getItemId(int position) {
        return position;
    }
    //外部的类内的方法通过调用setListAdapter(IconTextListAdapter obj)
    //实现将IconTextListAdapter作为Activtiy的显示(布局)。
    //在显示之前系统会调用getView这个函数来获得适配器内的每个元素的显示方式(内容)。
    //每个元素的显示都会调用getView这个函数,也就是在显示时有多少个元素就会调用多少次getView
    /** @param convertView The old view to overwrite, if one is passed
     * @returns a IconTextView that holds wraps around an IconText */
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.i("braincol","getView");
        //每个IconText的显示方式为IconTextView。
        IconTextView btv;
        if (convertView == null) {
            btv = new IconTextView(mContext, mItems.get(position));
        } else { // Reuse/Overwrite the View passed
            // We are assuming(!) that it is castable! 
            btv = (IconTextView) convertView;
            btv.setText(mItems.get(position).getText());
            btv.setIcon(mItems.get(position).getIcon());
        }
        return btv;
    }
}

第四步:使用IconTextListAdapter将我们自定义的布局显示在activity上,下面的代码的具体实现应该放在activity子类的某个成员方法中。

...
List<IconText> entries = new ArrayList<IconText>(); 
String text=" ";
Drawable icon = null;
...
for(...){
    ...
    text="xxx";
    icon=getResources().getDrawable(R.drawable.xxxx);
    ...
    //向ArrayList中添加元素
    entries.add(new IconifiedText(text,icon);    
    ...
}
...
//排序,entries之所以能使用Collections.sort来排序,
//是因为IconText 实现了 Comparable<IconText>接口
Collections.sort(entries);
//新建一个IconifiedTextListAdapter对象
IconTextListAdapter itla = new IconTextListAdapter(this);
//设置itla的内容(元素)。
itla.setListItems(entries);
//provide the cursor for listview
//将itla的每个元素都描绘(显示)在activity上。
this.setListAdapter(itla);
...

相关文章
|
XML 开发工具 Android开发
Android 深入了解 Window 、Activity、 View 三者关系(上)
Window、Activity、View都经常用到,但三者关系还是没有系统的理清,今天咱们就开始整理整理这三者的关系: Window:顶级窗口外观和行为策略的 抽象基类 。唯一实现是 PhoneWindow类。 Activity:四大组件之一,它提供一个界面让用户点击和各种滑动操作。 View:代表用户界面组件的基本构建块,UI 组件。
222 0
Android 深入了解 Window 、Activity、 View 三者关系(上)
|
缓存 Android开发
Android 深入了解 Window 、Activity、 View 三者关系(下)
addView 成功有一个标志就是能够接收触屏事件,通过对 setContentView 流程的分析,可以看出添加 View 的操作实质上是 PhoneWindow 在全盘操作,背后负责人是 WMS,反之 Activity 自始至终没什么参与感。但是我们也知道当触屏事件发生之后,Touch 事件首先是被传入到 Activity,然后才被下发到布局中的 ViewGroup 或者 View(Touch事件分发 了解一下)。那么 Touch 事件是如何传递到 Activity 上的呢?
212 0
|
Android开发
Activity、Window、View三者关系
目录介绍 01.Window,View,子Window 02.什么是Activity 03.什么是Window 04.什么是DecorView 05.什么是View 06.关系结构图 07.Window创建过程 08.
976 0
|
Android开发 数据格式 XML
Android 面试(八):说说 Activity、View、Window 之间的关系吧
连载内容镇楼:Android 面试(一):说说 Android 的四种启动模式Android 面试(二):如何理解 Activity 的生命周期Android 面试(三):用广播 BroadcastReceiver 更新 UI 界面真的好吗?Andro...
1928 0
|
Android开发 人机交互
Android View 及 Input 类之间关系
注:本系列文章的中涉及到的 Android 版本为官方 5.1.1 版本源码。 在一系统中,主要的内容为人机交互,这里对直接涉及到的内容即 界面 和 输入的关系进行简单分析。
873 0