2017年6月第一篇博文。
最近做项目越来越发对于程序语言的深入理解的重要性,否则很难有较大的成长。今天主要写关于如何利用Tablayout写微信底部栏的过程。Tab在中国的的很多应用App上都有应用,比如微信,QQ,网易新闻等。基于此,写下这篇博客。首先大家看一下做的效果:
首先我们先来分析一下代码结构,简单的微信底部栏主要的代码结构如下图所示:
细节入手
我们以微信为例,大家可以从图中可以看到,底部共有四个按钮(上面是文字,下面是图片)。我们首先给出XML文件,这里我们用的是merge标签,主要是Tab view主要是放在布局里面,如果大家想要详细的了解merge标签的作用,大家可以百度一下相关的博客,这里就不详细解释了。
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tex_Tab"
android:textColor="@color/colorPrimary"
android:textSize="12sp"/>
<ImageView
android:layout_height="20dp"
android:layout_width="20dp"
android:id="@+id/Img_Tab"
/>
</merge>
大家可以发现上面的布局没有下入数据,主要是为了大家写入不同数据方便,我们还需要些一个Tabview类来写入数据。
public class Tabview extends LinearLayout implements View.OnClickListener {
private TextView txt_tab;
private ImageView Img_tab;
public Tabview(Context context) {
super(context);
initView(context);
}
public Tabview(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public Tabview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public void initView(Context context){
setOrientation(VERTICAL);
setGravity(Gravity.CENTER);
LayoutInflater.from(context).inflate(R.layout.tabview,this,true);
txt_tab=(TextView)findViewById(R.id.tex_Tab);
Img_tab=(ImageView)findViewById(R.id.Img_Tab);
}
public void initdata(TabItem tabItem){
txt_tab.setText(tabItem.lableResId);
Img_tab.setImageResource(tabItem.imageResId);
}
@Override
public void onClick(View v) {
}
}
从上述代码中我们可以看出,initView()主要是写入控件,initdata()主要用于写入数据,下面写入数据时会调用改方法。
TabLayout
从程序结构图,我们可以看到位于Activity和TabView之间的Tablayout。我们可以从简单程序的结构示意图中可以发现,它的主要作用是向下写入数据,从上面接收数据。
public class TabLayout extends LinearLayout implements View.OnClickListener{
private ArrayList<TabItem> tabs;
private OnTabClickListener listener;
private int tabCount;
public TabLayout(Context context) {
super(context);
initView();
}
public TabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public TabLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
private void initView(){
setOrientation(HORIZONTAL);
}
public void initData(ArrayList<TabItem> tabs, OnTabClickListener listener){
this.listener=listener;
this.tabs=tabs;
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
params.weight=1;
if (tabs!=null&&tabs.size()>0){
tabCount=tabs.size();
Tabview mTabView=null; for(int i=0;i< tabs.size();i++){
mTabView=new Tabview(getContext());
mTabView.setTag(tabs.get(i));
mTabView.initdata(tabs.get(i));
mTabView.setOnClickListener(this);
addView(mTabView,params);
}
}else{
throw new IllegalArgumentException("tabs can not be empty");
}
}
@Override
public void onClick(View v) {
listener.onTabClick((TabItem) v.getTag());
}
public interface OnTabClickListener{
void onTabClick(TabItem tabItem);
}
}
在写入数据时,会用到相当于C++结构体类似的类。
public class TabItem {
public int imageResId;
public int lableResId;
public TabItem(int imageResId,int lableResId){
this.imageResId=imageResId;
this.lableResId=lableResId;
}
}
这里TabLayout实际上是一个容器,底部需要几个Tab按钮,就在MainActiviy里new几个然后add到TabLayout即可。所以有一天产品经理跟你说需要增加一个按钮,只需要再new一个add进去就好,又有一天boss说把底部Tab栏顺序调整下呗,就只要调整下new出的TabView顺序即可。
下面给出该程序的主程序:
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabClickListener{
private Tabview mtabview;
private ArrayList tabs;
TabItem tabItem;
private TabLayout mtablayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initview();
initData();
}
public void initview(){
mtablayout=(TabLayout)findViewById(R.id.Tab_layout);
}
public void initData(){
tabs=new ArrayList<>();
tabs = new ArrayList<>();
tabs.add(new TabItem(R.drawable.selector_tab_msg, R.string.wechat));
tabs.add(new TabItem(R.drawable.selector_tab_contact, R.string.contacts) );
tabs.add(new TabItem(R.drawable.selector_tab_moments, R.string.discover));
tabs.add(new TabItem(R.drawable.selector_tab_profile, R.string.me));
mtablayout.initData(tabs, this);
}
@Override
public void onTabClick(TabItem tabItem) {
Toast.makeText(MainActivity.this,"你好",Toast.LENGTH_LONG).show();
}
}
给出该程序的主布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
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.example.zhongzhi.newtablayout.MainActivity">
<com.example.zhongzhi.newtablayout.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/Tab_layout"></com.example.zhongzhi.newtablayout.TabLayout>
</RelativeLayout>
这样我们就可以实现上述微信底部栏的程序了。如果大家有需要可以联系我,我把源程序发给大家。是不是简单。