今天我们要实现的效果如下:
当然列表中的标签显示的个数是可控的,实现个数可控的标签的话,我们就需要自定义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情绪控_