仿写Android淘宝客户端界面(一)——仿Tab选项卡切换界面
为了加强布局的功底,最近准备仿写一下淘宝的Android客户端。
我截取了几张淘宝客户端的截图
如下:
我对这5张截图进行了一个分析,初步得出的结论是
布局使用了一个RelativeLayout,底部放置了一个LinearLayout,作为底Tab。由于使用的图标是下自iconfont,使用图标不是ImageView,使用的是TextView。对于iconfont的用法,请自行学习,地址:http://www.iconfont.cn/。
对此在截图上进行简单的布局分析
布局具体为RelativeLayout,底部为一个LinearLayout,属性设置为android:layout_alignParentBottom=”true”,内容部分为一个FrameLayout,放置fragment。
底部tab为一个横向的LinearLayout,平分为5个部分,每部分为一个属向的LinearLayout,平分为2部分。上方为图标,下方为文字。
具体的布局代码如下:
<?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"> <FrameLayout android:id="@+id/frame_home_page" android:layout_width="match_parent" android:layout_height="match_parent"></FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:layout_alignParentBottom="true" android:background="@android:color/white" android:orientation="horizontal"> <LinearLayout android:id="@+id/linear_homepage_home_fill" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/tv_homepage_home_fill_up" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="@string/home_fill" android:textSize="25sp" /> <TextView android:id="@+id/tv_homepage_home_fill_down" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="首页" android:textColor="@color/textPrimaryColor" android:textSize="10sp" /> </LinearLayout> <LinearLayout android:id="@+id/linear_homepage_we" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/tv_homepage_we_up" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="@string/we" android:textColor="@color/textPrimaryColor" android:textSize="25sp" /> <TextView android:id="@+id/tv_homepage_we_down" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="微淘" android:textColor="@color/textPrimaryColor" android:textSize="10sp" /> </LinearLayout> <LinearLayout android:id="@+id/linear_homepage_community" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/tv_homepage_community_up" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="@string/community" android:textColor="@color/textPrimaryColor" android:textSize="25sp" /> <TextView android:id="@+id/tv_homepage_community_down" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="社区" android:textColor="@color/textPrimaryColor" android:textSize="10sp" /> </LinearLayout> <LinearLayout android:id="@+id/linear_homepage_cart" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/tv_cart_up" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="@string/cart" android:textColor="@color/textPrimaryColor" android:textSize="25sp" /> <TextView android:id="@+id/tv_cart_down" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="购物车" android:textColor="@color/textPrimaryColor" android:textSize="10sp" /> </LinearLayout> <LinearLayout android:id="@+id/linear_homepage_my" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/tv_homepage_my_up" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="@string/community" android:textColor="@color/textPrimaryColor" android:textSize="25sp" /> <TextView android:id="@+id/tv_homepage_my_down" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="我的淘宝" android:textColor="@color/textPrimaryColor" android:textSize="10sp" /> </LinearLayout> </LinearLayout></RelativeLayout>
写完了布局,我还发现了淘宝客户端一个细节。就是点击tab切换的时候,从A选项卡点击B进行切换,再点击回退按钮的时候,会返回A选项卡视图。重复单机某个按钮到时候不会重复显示,如果点击首页选项卡,点击回退键会直接退出应用程序。
刚开始我准备使用Viewpager,重写它的方法
viewpager.setOTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; }};)
虽然这个方法实现了禁止滑动,但是点击第一个Tab和第五个Tab进行切换时,会出现第一个界面像第五个界面陆续滑动的过程,很显然淘宝的客户端不是用这个实现,所以我选择了想FrameLayout中添加Fragmen。不使用ViewPager。
于是代码的逻辑设定为点击每一个LinearLayout的时候切换Fragment,然后将所在的2个TextView的颜色变为淘宝的橙色。
编写方法void addFragment(Fragment),进行fragment的添加。
private void addFragment(Fragment fragment) { fragmentManager.beginTransaction().replace(R.id.frame_home_page, fragment).commit();}
由于每次点击的时候只讲选中的LinearLayout中的2个TextView的文字颜色更改,所以在点击更改之前需要先把5组的TextView的颜色都改变为默认的灰色(#646464)。
编写方法void initTabColor()
private void initTabColor() { tvHomeFillUp.setTextColor(TEXT_PRIMARY_COLOR); tvHomeFillDown.setTextColor(TEXT_PRIMARY_COLOR); tvWeUp.setTextColor(TEXT_PRIMARY_COLOR); tvWeDown.setTextColor(TEXT_PRIMARY_COLOR); tvCommunityUp.setTextColor(TEXT_PRIMARY_COLOR); tvCommunityDown.setTextColor(TEXT_PRIMARY_COLOR); tvCartUp.setTextColor(TEXT_PRIMARY_COLOR); tvCartDown.setTextColor(TEXT_PRIMARY_COLOR); tvMyUp.setTextColor(TEXT_PRIMARY_COLOR); tvMyDown.setTextColor(TEXT_PRIMARY_COLOR); }
现在问题来了,那么如何实现fragment的切换呢?为了思路简单,我采取了不模拟fragment返回栈。将所有的LinearLayout和TextView分别放入一个ArrayList<>里面去。然后建立一个Stack,每次切换Tab的时候,就把下标压栈。如果压入的下标为0(点击首页Tab),则先把栈清空,再将下标0压入栈中。
即
stack.clear();pushToStack(0);
编写函数
//压栈 private void pushToStack(int index) { if (stack.isEmpty()) { stack.push(index); //如果栈为空,则直接压入下标 } else { int top = stack.peek(); //取出栈顶元素值 if (top == index) { //如果栈顶和index相等 //说明前一次点击的Tab和现在点击的是同一个Tab //不需要重复操作进行压栈 } else { stack.push(index); } } }
这样,淘宝客户端每个选项卡的切换效果就实现了
附上完整代码
package example.com.taobao;import android.app.Activity;import android.app.Fragment;import android.app.FragmentManager;import android.graphics.Typeface;import android.os.Bundle;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;import java.util.ArrayList;import java.util.Stack;import example.com.fragment.CartFragment;import example.com.fragment.CommunityFragment;import example.com.fragment.HomeFillFragment;import example.com.fragment.MyFragment;import example.com.fragment.WeFragment;/** * 仿淘宝客户端首页 */public class HomePageActivity extends Activity implements View.OnClickListener { private LinearLayout linearHomeFill; private LinearLayout linearWe; private LinearLayout linearCommunity; private LinearLayout linearCart; private LinearLayout linearMy; private TextView tvHomeFillUp; private TextView tvHomeFillDown; private TextView tvWeUp; private TextView tvWeDown; private TextView tvCommunityUp; private TextView tvCommunityDown; private TextView tvCartUp; private TextView tvCartDown; private TextView tvMyUp; private TextView tvMyDown; private Typeface typeFace; private static int TAOBAO_PRIMARY_COLOR; private static int TEXT_PRIMARY_COLOR; private HomeFillFragment homeFillFragment = new HomeFillFragment(); private WeFragment weFragment = new WeFragment(); private CommunityFragment communityFragment = new CommunityFragment(); private CartFragment cartFragment = new CartFragment(); private MyFragment myFragment = new MyFragment(); ArrayList<Fragment> fragments = new ArrayList<>(); ArrayList<TextView> upTvs = new ArrayList<>(); ArrayList<TextView> downTvs = new ArrayList<>(); FragmentManager fragmentManager = getFragmentManager(); private Stack<Integer> stack = new Stack<>(); //栈,存放下标值,模拟fragment返回栈 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home_page); typeFace = Typeface.createFromAsset(getAssets(), "iconfont/iconfont.ttf"); TAOBAO_PRIMARY_COLOR = getResources().getColor(R.color.taobaoPrimaryColor); TEXT_PRIMARY_COLOR = getResources().getColor(R.color.textPrimaryColor); init(); initFragments(); initTextViews(); initAttr(); initEvent(); } private void initTextViews() { upTvs.add(tvHomeFillUp); downTvs.add(tvHomeFillDown); upTvs.add(tvWeUp); downTvs.add(tvWeDown); upTvs.add(tvCommunityUp); downTvs.add(tvCommunityDown); upTvs.add(tvCartUp); downTvs.add(tvCartDown); upTvs.add(tvMyUp); downTvs.add(tvMyDown); } private void initFragments() { fragments.add(homeFillFragment); fragments.add(weFragment); fragments.add(communityFragment); fragments.add(cartFragment); fragments.add(myFragment); } private void init() { linearHomeFill = (LinearLayout) findViewById(R.id.linear_homepage_home_fill); linearWe = (LinearLayout) findViewById(R.id.linear_homepage_we); linearCommunity = (LinearLayout) findViewById(R.id.linear_homepage_community); linearCart = (LinearLayout) findViewById(R.id.linear_homepage_cart); linearMy = (LinearLayout) findViewById(R.id.linear_homepage_my); tvHomeFillUp = (TextView) findViewById(R.id.tv_homepage_home_fill_up); tvHomeFillDown = (TextView) findViewById(R.id.tv_homepage_home_fill_down); tvHomeFillUp.setTextColor(TAOBAO_PRIMARY_COLOR); tvHomeFillDown.setTextColor(TAOBAO_PRIMARY_COLOR); tvWeUp = (TextView) findViewById(R.id.tv_homepage_we_up); tvWeDown = (TextView) findViewById(R.id.tv_homepage_we_down); tvCommunityUp = (TextView) findViewById(R.id.tv_homepage_community_up); tvCommunityDown = (TextView) findViewById(R.id.tv_homepage_community_down); tvCartUp = (TextView) findViewById(R.id.tv_cart_up); tvCartDown = (TextView) findViewById(R.id.tv_cart_down); tvMyUp = (TextView) findViewById(R.id.tv_homepage_my_up); tvMyDown = (TextView) findViewById(R.id.tv_homepage_my_down); } private void initAttr() { tvHomeFillUp.setTypeface(typeFace); tvWeUp.setTypeface(typeFace); tvCommunityUp.setTypeface(typeFace); tvCartUp.setTypeface(typeFace); tvMyUp.setTypeface(typeFace); addFragment(homeFillFragment); stack.clear(); pushToStack(0); } private void initEvent() { linearHomeFill.setOnClickListener(this); linearWe.setOnClickListener(this); linearCommunity.setOnClickListener(this); linearCart.setOnClickListener(this); linearMy.setOnClickListener(this); } private void initTabColor() { tvHomeFillUp.setTextColor(TEXT_PRIMARY_COLOR); tvHomeFillDown.setTextColor(TEXT_PRIMARY_COLOR); tvWeUp.setTextColor(TEXT_PRIMARY_COLOR); tvWeDown.setTextColor(TEXT_PRIMARY_COLOR); tvCommunityUp.setTextColor(TEXT_PRIMARY_COLOR); tvCommunityDown.setTextColor(TEXT_PRIMARY_COLOR); tvCartUp.setTextColor(TEXT_PRIMARY_COLOR); tvCartDown.setTextColor(TEXT_PRIMARY_COLOR); tvMyUp.setTextColor(TEXT_PRIMARY_COLOR); tvMyDown.setTextColor(TEXT_PRIMARY_COLOR); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.linear_homepage_home_fill: initTabColor(); tvHomeFillUp.setTextColor(TAOBAO_PRIMARY_COLOR); tvHomeFillDown.setTextColor(TAOBAO_PRIMARY_COLOR); addFragment(homeFillFragment); stack.clear(); pushToStack(0); break; case R.id.linear_homepage_we: initTabColor(); tvWeUp.setTextColor(TAOBAO_PRIMARY_COLOR); tvWeDown.setTextColor(TAOBAO_PRIMARY_COLOR); addFragment(weFragment); pushToStack(1); break; case R.id.linear_homepage_community: initTabColor(); tvCommunityUp.setTextColor(TAOBAO_PRIMARY_COLOR); tvCommunityDown.setTextColor(TAOBAO_PRIMARY_COLOR); addFragment(communityFragment); pushToStack(2); break; case R.id.linear_homepage_cart: initTabColor(); tvCartUp.setTextColor(TAOBAO_PRIMARY_COLOR); tvCartDown.setTextColor(TAOBAO_PRIMARY_COLOR); addFragment(cartFragment); pushToStack(3); break; case R.id.linear_homepage_my: initTabColor(); tvMyUp.setTextColor(TAOBAO_PRIMARY_COLOR); tvMyDown.setTextColor(TAOBAO_PRIMARY_COLOR); addFragment(myFragment); pushToStack(4); break; default: break; } } private void addFragment(Fragment fragment) { fragmentManager.beginTransaction().replace(R.id.frame_home_page, fragment).commit(); } //压栈 private void pushToStack(int index) { if (stack.isEmpty()) { stack.push(index); } else { int top = stack.peek(); if (top == index) { } else { stack.push(index); } } } @Override public void onBackPressed() { if (stack.isEmpty()) { //返回栈为空,则直接退出 super.onBackPressed(); } else { stack.pop(); int top = stack.peek(); addFragment(fragments.get(top)); initTabColor(); upTvs.get(top).setTextColor(TAOBAO_PRIMARY_COLOR); downTvs.get(top).setTextColor(TAOBAO_PRIMARY_COLOR); } }}
更多相关文章
- Mac android 入门初探
- Android官方开发文档Training系列课程中文版:多样屏幕之支持不同
- android studio使用fragment标签出错:E/AndroidRuntime: FATAL EX
- Android(安卓)编程的几点总结
- Android中常见的热门标签的流式布局的实现
- Android中自定义一个View的方法详解
- 某一线互联网公司高薪招android高级开发工程师
- ArcGIS for Android示例解析之地图基础-----HelloWorld
- android中include文件的使用