«

一起学android之自定义控件一起制作自定义标签(39)

时间:2024-3-2 18:09     作者:韩俊     分类: Android


今天我们要实现的效果如下:


当然列表中的标签显示的个数是可控的,实现个数可控的标签的话,我们就需要自定义View。


我们自定义一个抽象类继承LinearLayout并实现我们定义的接口:


BaseTagView:

/**
 * 标签,继承此抽象类
 * @author LinHai Gu
 *
 * @param <T>
 */
public abstract class BaseTagView<T> extends LinearLayout implements SelectTag<T>{

    private Context mContext;

    public BaseTagView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        initView();
    }

    public BaseTagView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initView();
    }

    public BaseTagView(Context context) {
        super(context);
        mContext = context;
        initView();

    }

    private void initView() {

        setOrientation(LinearLayout.HORIZONTAL);
    }

    /**
     * 添加标签,可配
     * @param datas 数据源
     * @param num 显示的标签数
     */
    public void addTag(List<T> datas,int num) {
        removeAllViews();
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        params.setMargins(0, 0, 10, 0);
        if (datas.size() > num) {
            for (int i = 0; i < num; i++) {
                T data = datas.get(i);
                TextView textView = (TextView) LayoutInflater.from(mContext)
                        .inflate(R.layout.tagtext_view, null);
                textView.setText(getTag(data));
                textView.setLayoutParams(params);
                addView(textView);
            }
        } else {
            for (int i = 0; i < datas.size(); i++) {
                T data = datas.get(i);
                TextView textView = (TextView) LayoutInflater.from(mContext)
                        .inflate(R.layout.tagtext_view, null);
                textView.setText(getTag(data));
                textView.setLayoutParams(params);
                addView(textView);

            }
        }

    }

}


定义接口SelectTag:


/**
 * 
 * @author LinHai Gu
 *
 * @param <T>
 */
public interface SelectTag<T> {

    /**
     * 获取标签内容
     * @param data
     * @return
     */
    public abstract String getTag(T data);

}


在这里为什么用到了泛型,这是因为我们需要的是一个公共的控件,而不是为某一个界面而写的。

在BaseTagView抽象类中的addTag方法中需要导入一个TextView布局文件:


tagtext_view:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/text_line" 
    android:textSize="12dp"
    android:textColor="#999999"
    android:padding="2dp"

   >
</TextView>


text_line:是专门给TextView外部添加标签的边框,当然你可以根据需要制作一些好看的标签样式


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
    <solid android:color="@android:color/transparent" />   
    <corners android:topLeftRadius="1dp"  
             android:topRightRadius="1dp"   
             android:bottomRightRadius="1dp"  
             android:bottomLeftRadius="1dp"/>
    <stroke android:width="1dp"
        android:color="#999999"/>   
</shape>

以上我们的公共控件基本完成。


这时候假设有一个项目第一个页面从服务器获取到了标签列表,并显示在列表中,标签的值存放在一个PageObject对象中:

PageObject:

/**
 * 假设这是某页面请求到的标签数据
 * @author LinHai Gu
 *
 */
public class PageObject implements Serializable{
    private static final long serialVersionUID = 100230230204204021L;
    public String tagName;
}

接着我们就要显示这些标签,因此我们可以为不同的模块去创建不同的标签,假设第一个界面的标签View是这样的:

public class PageOneTagView extends BaseTagView<PageObject>{

    public PageOneTagView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public PageOneTagView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PageOneTagView(Context context) {
        super(context);
    }

    public void setTagList(ArrayList<PageObject> list,int num){
        addTag(list,num);
    }

    @Override
    public String getTag(PageObject data) {
        return data.tagName;
    }

}

通过子类定义setTagList方法传入我们想要显示的标签列表,并显示的个数就行了。


以下使我们的主布局:

MainActivity:

public class MainActivity extends Activity {

    private Datapter datapter=new Datapter();
    private ArrayList<PageObject> list=new ArrayList<PageObject>();
    private ListView lv_tag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     
        initData();
        initView();
    }

    /**
     * 假设这边是从服务获取到的标签列表
     */
    private void initData(){
        for(int i=0;i<10;i++){
            PageObject obj=new PageObject();
            obj.tagName="标签"+i;
            list.add(obj);
        }
    }

    private void initView(){
        lv_tag=(ListView)findViewById(R.id.lv_list);
        lv_tag.setAdapter(datapter);
    }

    class Datapter extends BaseAdapter {

        @Override
        public int getCount() {
            return 23;
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            viewHolder viewh;
            if (convertView == null) {
                viewh = new viewHolder();
                convertView = LayoutInflater.from(MainActivity.this).inflate(
                        R.layout.list_item, parent, false);
                viewh.tag = (PageOneTagView) convertView.findViewById(R.id.page_tag);
                convertView.setTag(viewh);
            } else {
                viewh = (viewHolder) convertView.getTag();
            }
            /*
             * 添加标签,并显示4个标签
             */
            viewh.tag.setTagList(list, 4);

            return convertView;
        }

    }

    class viewHolder {
        public PageOneTagView tag;
    }
}

activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.bill.MainActivity" >

    <ListView
        android:id="@+id/lv_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</RelativeLayout>


list_item:(导入我们继承BaseTagView的类)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/iv_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <com.bill.page1.PageOneTagView
        android:id="@+id/page_tag"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@id/iv_logo" >
    </com.bill.page1.PageOneTagView>

</RelativeLayout>



个人GitHub项目地址:https://github.com/LinhaiGu/TabView

转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/45919871情绪控_





标签: android

热门推荐