蘑菇街作为中国最大女性购物社区,其APP的设计水平也毋庸置疑的,最近博客将连续来仿造一个蘑菇街的APP的界面设计。
(1)准备工作
在阅读郭霖大神的博客时有人问里面使用的美工素材怎么得到的,其实很简单,下载一个APP,把APK格式修改成rar后解压,你会在目录下看到所有的素材。
随后,看看APP的界面:

第一个是启动界面,第二个是主界面,先来看第一个界面。
(1)启动界面(Splash)。
启动界面也叫Splash界面,是APP启动时的第一画面,主要用于介绍应用、宣传或者加载数据,或者兼而有之。这里之所以要单独拿出来是因为这个应用有个独特的,它的LOGO是透明渐变出现的,也就是淡入效果,我们知道ANDROID主要有四种动画:透明动画、缩放、位移、旋转,分别使用的AlphaAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation,这里我们使用AlphaAnimation。
界面布局很简单,如activity_loading.xml:
-
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:orientation="vertical"
-
android:gravity="center"
-
android:background="@drawable/init_bg">
-
<ImageView
-
android:id="@+id/logo"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:src="@drawable/init_logo"/>
-
</LinearLayout>
新建一个LoadingActivity类:如下代码:
-
public class LoadingActivity extends Activity{
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
-
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
-
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
setContentView(R.layout.activity_loading);
-
ImageView view =(ImageView) findViewById(R.id.logo);
-
AlphaAnimation aa = new AlphaAnimation(0.01f,1.0f);
-
aa.setDuration(1500);
-
view.startAnimation(aa);
-
aa.setAnimationListener(new AnimationListener(){
-
-
@Override
-
public void onAnimationEnd(Animation arg0) {
-
redirectTo();
-
}
-
@Override
-
public void onAnimationRepeat(Animation animation) {
-
-
}
-
@Override
-
public void onAnimationStart(Animation animation) {
-
-
}
-
-
});
-
}
-
-
-
-
-
private void redirectTo(){
-
Intent intent = new Intent(this, MainActivity.class);
-
startActivity(intent);
-
finish();
-
}
-
-
-
}
注意2个地方:a. AlphaAnimation aa = new AlphaAnimation(0.01f,1.0f); 构造方法:AlphaAnimation(float fromAlpha, float toAlpha),表示从透明度0.01到1.0的渐变,我们知道0.0表示全透明,1.0表示完全不透明.
b. onAnimationEnd方法,顾名思义,表示:在动画结束后自动执行这个方法,这里当然是跳转到主界面了。运行后其效果如下:

是不是很简单,以后做启动画面都可以采用类似的方法。
总结要点:AlphaAnimation类
(1)主界面。
看看原图,如下:

中间的内容先不管,我们看ActionBar和底部菜单,上面是一个自定义的ActionBar,下面是一个切换菜单,而且下面菜单在改变的时候上面的ActionBar也在变。我们这里采用的设计方法是fragment+activity混合使用,底部菜单使用RadioButton,中间留出一个活动的fragment
先来看ActionBar,观察发现ActionBar分为2类,第一个是图片标题,另外一个是文字标题。
所以自定义的actionBar需要2个xml布局文件,分别命名为:actionbar_index.xml和actionbar_usu.xml
其XML布局分别为:actionbar_index.xml
-
<?xml version="1.0" encoding="utf-8"?>
-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="match_parent"
-
android:layout_height="fill_parent"
-
android:id="@+id/index_action_layout"
-
android:background="@drawable/title_bg">
-
-
<ImageButton
-
android:id="@+id/btn_slideMenu"
-
android:layout_width="wrap_content"
-
android:layout_height="match_parent"
-
android:layout_gravity="center"
-
android:background="@android:color/transparent"
-
android:clickable="true"
-
android:paddingLeft="8dip"
-
android:src="@drawable/index_logo" />
-
-
<ImageButton android:id="@+id/btn_main_qrcode"
-
android:layout_width="wrap_content"
-
android:layout_height="match_parent"
-
android:background="@android:color/transparent"
-
android:src="@drawable/icon_qc"
-
android:paddingRight="8dip"
-
android:clickable="true"
-
android:layout_gravity="right|center_vertical"/>
-
</FrameLayout>
actionbar_usu.xml
-
<?xml version="1.0" encoding="utf-8"?>
-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="match_parent"
-
android:layout_height="fill_parent"
-
android:id="@+id/index_action_layout"
-
android:background="@drawable/title_bg">
-
<TextView
-
android:id="@+id/tv_title"
-
android:layout_width="wrap_content"
-
android:layout_height="match_parent"
-
android:layout_gravity="center"
-
android:gravity="center"
-
android:textColor="@color/white1"
-
android:textSize="@dimen/actionbar_title"
-
android:background="@android:color/transparent"
-
android:clickable="true"
-
android:paddingLeft="8dip"
-
/>
-
-
</FrameLayout>
这个不多讲,唯一值得注意的是需要使用FrameLayout来布局,其中一些strings 、colors以及dimens是自己定义的最后我会将代码传上去。新建一个ActionBarTool工具类,主要用来设置每个界面的ActionBar,代码如下:
-
public class ActionBarTool {
-
Activity activity;
-
public ActionBarTool(Activity activity){
-
this.activity=activity;
-
}
-
-
-
-
public void setIndexActionBar(){
-
ActionBar actionBar=activity.getActionBar();
-
ActionBar.LayoutParams params=new ActionBar.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT,Gravity.CENTER );
-
View view=LayoutInflater.from(activity).inflate(R.layout.actionbar_index, null);
-
actionBar.setCustomView(view,params);
-
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
-
actionBar.setDisplayShowCustomEnabled(true);
-
}
-
-
-
-
-
-
public void setUsuActionBar(String title){
-
ActionBar actionBar=activity.getActionBar();
-
ActionBar.LayoutParams params=new ActionBar.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT,Gravity.CENTER );
-
View view=LayoutInflater.from(activity).inflate(R.layout.actionbar_usu, null);
-
actionBar.setCustomView(view,params);
-
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
-
actionBar.setDisplayShowCustomEnabled(true);
-
TextView tv_title=(TextView)activity.findViewById(R.id.tv_title);
-
tv_title.setText(title);
-
}
-
}
这是自定义目录的一般做法,但是安卓的设计文档里面是不推荐这么使用的,因为这样会破坏ActionBar的一些灵活性,而且到后期很难管理,这里之所以使用是因为文字居中需要自己定义视图,其实可以直接用背景来代替,这样也能实现文字居中,而且不会破坏actonbar的灵活性。
再来看看底部菜单:main.XML文件如下
-
<?xml version="1.0" encoding="utf-8"?><LinearLayout 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:background="#fff"
-
android:orientation="vertical" >
-
<FrameLayout
-
android:id="@+id/content"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:layout_weight="1"
-
android:background="#fff"/>
-
<RadioGroup
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:background="@color/gray"
-
android:layout_marginTop="2dp"
-
android:layout_weight="10"
-
android:gravity="center"
-
android:orientation="horizontal" >
-
<RadioButton
-
android:id="@+id/fragment_index"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_weight="1"
-
android:button="@null"
-
android:drawableTop="@drawable/index_indicator"
-
android:gravity="center"
-
android:text="@string/index"
-
android:textColor="@color/white"
-
android:textSize="12sp" />
-
-
<RadioButton
-
android:id="@+id/fragment_category"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_weight="1"
-
android:button="@null"
-
android:drawableTop="@drawable/category_indicator"
-
android:gravity="center"
-
android:text="@string/category"
-
android:textColor="@color/white"
-
android:textSize="12sp" />
-
<RadioButton
-
android:id="@+id/fragment_discovery"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_weight="1"
-
android:button="@null"
-
android:drawableTop="@drawable/discovery"
-
android:gravity="center"
-
android:text="@string/discovery"
-
android:textColor="@color/white"
-
android:textSize="12sp" />
-
-
<RadioButton
-
android:id="@+id/fragment_cart"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_weight="1"
-
android:button="@null"
-
android:drawablePadding="3dip"
-
android:drawableTop="@drawable/cart_tab_icon_dark"
-
android:gravity="center"
-
android:text="@string/cart"
-
android:textColor="@color/white"
-
android:textSize="12sp" />
-
-
<RadioButton
-
android:id="@+id/fragment_my"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_weight="1"
-
android:button="@null"
-
android:drawablePadding="3dip"
-
android:drawableTop="@drawable/my_indicator"
-
android:gravity="center"
-
android:text="@string/my"
-
android:textColor="@color/white"
-
android:textSize="12sp" />
-
</RadioGroup>
-
</LinearLayout>
RadioGroup +活动的FrameLayout 构成了整个页面的布局。
接下来是mian 页面的切换代码,MainActivity.java
-
public class MainActivity extends FragmentActivity {
-
-
RadioButton btn_index, btn_category, btn_discovery, btn_cart, btn_my;
-
private Fragment fragment;
-
FragmentManager fragmentManager;
-
ActionBarTool actionbarTool;
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.main);
-
InitUI();
-
}
-
-
-
-
-
private void InitUI() {
-
actionbarTool=new ActionBarTool(this);
-
btn_index = (RadioButton) findViewById(R.id.fragment_index);
-
btn_category = (RadioButton) findViewById(R.id.fragment_category);
-
btn_discovery = (RadioButton) findViewById(R.id.fragment_discovery);
-
btn_cart = (RadioButton) findViewById(R.id.fragment_cart);
-
btn_my = (RadioButton) findViewById(R.id.fragment_my);
-
btn_my.setOnClickListener(new switchFragment());
-
btn_cart.setOnClickListener(new switchFragment());
-
btn_discovery.setOnClickListener(new switchFragment());
-
btn_category.setOnClickListener(new switchFragment());
-
btn_index.setOnClickListener(new switchFragment());
-
fragment = new IndexFragment();
-
actionbarTool.setIndexActionBar();
-
btn_index.setTextColor(getResources().getColor(R.color.red));
-
btn_index.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.index_indicator_s), null, null);
-
fragmentManager =getSupportFragmentManager();
-
if (fragment != null) {
-
fragmentManager.beginTransaction()
-
.replace(R.id.content, fragment).commit();
-
} else {
-
Log.e("MainActivity", "Error in creating fragment");
-
}
-
}
-
-
-
-
-
-
-
class switchFragment implements View.OnClickListener {
-
@Override
-
public void onClick(View arg0) {
-
InitBg();
-
switch (arg0.getId()) {
-
case R.id.fragment_index:
-
fragment = new IndexFragment();
-
actionbarTool.setIndexActionBar();
-
btn_index.setTextColor(getResources().getColor(R.color.red));
-
btn_index.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.index_indicator_s), null, null);
-
break;
-
case R.id.fragment_category:
-
fragment = new CategoryFragment();
-
actionbarTool.setUsuActionBar("分类");
-
btn_category.setTextColor(getResources().getColor(R.color.red));
-
btn_category.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.category_indicator_s), null, null);
-
break;
-
case R.id.fragment_discovery:
-
fragment = new DiscoveryFragment();
-
actionbarTool.setUsuActionBar("发现");
-
btn_discovery.setTextColor(getResources().getColor(R.color.red));
-
btn_discovery.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.discovery_s), null, null);
-
break;
-
case R.id.fragment_cart:
-
fragment = new CartFragment();
-
actionbarTool.setUsuActionBar("我的购物车");
-
btn_cart.setTextColor(getResources().getColor(R.color.red));
-
btn_cart.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.cart_tab_icon_red), null, null);
-
break;
-
case R.id.fragment_my:
-
fragment = new MyFragment();
-
-
btn_my.setTextColor(getResources().getColor(R.color.red));
-
btn_my.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.my_indicator_s), null, null);
-
break;
-
}
-
if (fragment != null) {
-
fragmentManager.beginTransaction()
-
.replace(R.id.content, fragment).commit();
-
} else {
-
Log.e("MainActivity", "Error in creating fragment");
-
}
-
-
}
-
-
}
-
-
-
-
-
-
private void InitBg(){
-
btn_index.setTextColor(getResources().getColor(R.color.white));
-
btn_index.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.index_indicator), null, null);
-
btn_category.setTextColor(getResources().getColor(R.color.white));
-
btn_category.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.category_indicator), null, null);
-
btn_cart.setTextColor(getResources().getColor(R.color.white));
-
btn_cart.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.cart_tab_icon_dark), null, null);
-
btn_discovery.setTextColor(getResources().getColor(R.color.white));
-
btn_discovery.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.discovery), null, null);
-
btn_my.setTextColor(getResources().getColor(R.color.white));
-
btn_my.setCompoundDrawablesWithIntrinsicBounds(null,
-
getResources().getDrawable(R.drawable.my_indicator), null, null);
-
}
-
-
@Override
-
public boolean onCreateOptionsMenu(Menu menu) {
-
return true;
-
}
-
-
}
其他页面的fragment.类似,布局文件是空布局:
-
public class IndexFragment extends Fragment{
-
-
@Override
-
public void onActivityCreated(Bundle savedInstanceState) {
-
-
super.onActivityCreated(savedInstanceState);
-
}
-
-
@Override
-
public View onCreateView(LayoutInflater inflater, ViewGroup container,
-
Bundle savedInstanceState) {
-
return inflater.inflate(R.layout.fragment_index, container, false);
-
}
-
-
-
-
}
上面的主要代码是:switchFragment类,是切换fragment的,通过fragmentManager.beginTransaction().replace(R.id.content, fragment).commit();来替换当前的fragment,在替换的时候需要先使用InitBg()初始化按钮的颜色,在来改变按钮的字体颜色和图标。效果如下:

今天我们来重点来仿照一下第一个底部菜单“爱逛”,首先我们来分解一下功能区域:

1.功能区域分解
(1) PageTabs左右切换菜单:这里我们使用第三方开源插件,不过需要自己进行修改,采用的是ViewPage进行页面的切换,左右滑动。
(2) 图片轮播:ViewGroup+Viewpage每一个ViewGroup存储一个按压效果的dot和一张图片,随着手指的滑动进行图片之间的切换,当然我们这里只使用五张图片。
(3)更新时间:这个不说了,就是设置时间,这里找不到图片我自己设定固定值,当然也可以通过代码设置。
(4)第一个列表,第二个列表,我们观察布局可知,下面2个布局的大小是分别占用了屏幕的一般,我们可以通过设置权值属性来设置大小,也就是
-
<span style="white-space:pre"> </span>android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:layout_weight="2"
第一个布局是线性布局的,线性布局里面包括一个更新时间的一些TextView控件和一个GridView控件,第二个布局是一个单独的GridView控件
2.实现方式
(1) PageTabs:
第一个难点毋庸置疑就是PageTabs菜单,所幸这方面的开源组件挺多,我们可以使用郭霖大神推荐的PagerSlidingTabStrip,当然也要进行修改,修改包括横条的颜色。每一个PageTabs就是一个Fragment,因为放置这个PageTabs的本身就是一个Fragment,所以我们需要注意,在使用FragmentManager()的地方,必须要使用当前Fragment的子FragmentManager,否则会报错。
-
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:orientation="vertical"
-
android:background="#EEEEEE">
-
-
<com.blog.mogujie.tool.PagerSlidingTabStrip
-
android:id="@+id/tabs"
-
android:layout_width="match_parent"
-
android:layout_height="40dp" />
-
-
<android.support.v4.view.ViewPager
-
android:id="@+id/pager"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content" />
-
-
</LinearLayout>
PagerSlidingTabStrip为自定义控件,也就是第三方插件,ViewPager用来显示每一个页面的大小,但是注意到修改滚动条的长度,修改代码如下:
-
@Override
-
protected void onDraw(Canvas canvas) {
-
super.onDraw(canvas);
-
-
if (isInEditMode() || tabCount == 0) {
-
return;
-
}
-
-
final int height = getHeight();
-
-
-
rectPaint.setColor(underlineColor);
-
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
-
-
-
rectPaint.setColor(indicatorColor);
-
-
-
View currentTab = tabsContainer.getChildAt(currentPosition);
-
float lineLeft = currentTab.getLeft();
-
float lineRight = currentTab.getRight();
-
-
-
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
-
-
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
-
final float nextTabLeft = nextTab.getLeft();
-
final float nextTabRight = nextTab.getRight();
-
-
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
-
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
-
}
-
-
canvas.drawRect(lineLeft+100, height - indicatorHeight, lineRight-100, height, rectPaint);
-
-
-
-
dividerPaint.setColor(dividerColor);
-
for (int i = 0; i < tabCount - 1; i++) {
-
View tab = tabsContainer.getChildAt(i);
-
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
-
}
-
}
主要看第这一行
canvas.drawRect(lineLeft+100, height - indicatorHeight, lineRight-100, height, rectPaint);
这行lineLeft+100,lineRight-100设置左右两边同时减小100的长度。
设置IndexFragment代码,该代码就是“精选”菜单区域Fragment,代码如下:
-
public class IndexFragment extends Fragment {
-
private PagerSlidingTabStrip tabs;
-
private DisplayMetrics dm;
-
private String[] titles = { "精选", "搭配", "团购" };
-
private ViewPager pager;
-
private Fragment fragment;
-
@Override
-
public void onActivityCreated(Bundle savedInstanceState) {
-
super.onActivityCreated(savedInstanceState);
-
dm = getResources().getDisplayMetrics();
-
pager = (ViewPager) getView().findViewById(R.id.pager);
-
tabs = (PagerSlidingTabStrip) getView().findViewById(R.id.tabs);
-
-
-
pager.setAdapter(new PagerAdapter(this.getChildFragmentManager()));
-
tabs.setViewPager(pager);
-
InitTabsConfig();
-
}
-
-
@Override
-
public View onCreateView(LayoutInflater inflater, ViewGroup container,
-
Bundle savedInstanceState) {
-
return inflater.inflate(R.layout.fragment_index, container, false);
-
}
-
-
private void InitTabsConfig() {
-
-
tabs.setShouldExpand(true);
-
-
tabs.setDividerColor(Color.TRANSPARENT);
-
-
tabs.setUnderlineHeight((int) TypedValue.applyDimension(
-
TypedValue.COMPLEX_UNIT_DIP, 1, dm));
-
-
tabs.setIndicatorHeight((int) TypedValue.applyDimension(
-
TypedValue.COMPLEX_UNIT_DIP, 2, dm));
-
-
tabs.setTextSize((int) TypedValue.applyDimension(
-
TypedValue.COMPLEX_UNIT_SP, 16, dm));
-
-
tabs.setIndicatorColor(getResources().getColor(R.color.red));
-
-
tabs.setSelectedTextColor(getResources().getColor(R.color.red));
-
-
tabs.setTabBackground(0);
-
}
-
-
-
-
-
-
public class PagerAdapter extends FragmentStatePagerAdapter {
-
public PagerAdapter(FragmentManager fm) {
-
super(fm);
-
}
-
-
@Override
-
public CharSequence getPageTitle(int position) {
-
return titles[position];
-
}
-
-
@Override
-
public int getCount() {
-
return titles.length;
-
}
-
-
@Override
-
public Fragment getItem(int position) {
-
switch (position) {
-
case 0:
-
fragment = new GoodsFargment();
-
break;
-
case 1:
-
fragment = new ShopingsFragment();
-
break;
-
case 2:
-
fragment = new MatchFragment();
-
break;
-
default:
-
break;
-
}
-
return fragment;
-
}
-
-
}
-
-
}
注意到代码,这里使用this.getChildFragmentManager()来表示当前的Fragment为子Fragment,不能使用getActivity().getSupportFragmentManager(),否则在切换时候会出错,第二个地方为第X行,这里继承的是 FragmentStatePagerAdapte,而非FragmentPagerAdapter。
(2)图片轮播
我们知道OnTouch事件的响应机制是逐级响应的,他会自动响应最底层的View,因此考虑到图片轮播需要左右滑动,而PageTabs也会左右滑动,并且PageTabs在图片轮转View的下一层,如果使用原生控件,系统会优先响应PageTabs而不会响应ViewPage的图片滑动;因此需要考虑,重写ViewPager控件,让该控件只会响应自己的左右滑动事件,其父视图的View左右滑动事件不响应。
-
public class ChildViewPager extends ViewPager {
-
public ChildViewPager(Context context, AttributeSet attrs) {
-
super(context, attrs);
-
-
}
-
-
public ChildViewPager(Context context) {
-
super(context);
-
-
}
-
-
@Override
-
public boolean onInterceptTouchEvent(MotionEvent arg0) {
-
-
-
return true;
-
}
-
-
-
@Override
-
public boolean onTouchEvent(MotionEvent arg0) {
-
getParent().requestDisallowInterceptTouchEvent(true);
-
return super.onTouchEvent(arg0);
-
}
-
}
代码很少,主要是这一句getParent().requestDisallowInterceptTouchEvent(true);
设置父控件不响应OnTouch事件,而是交给当前控件的onTouchEvent事件,从而阻止PageTabS的滑动,响应当前控件的滑动事件
最后这是ViewPage的数据适配器,添加图片和点,进行左右的移动,定义ImgaePagerAdapter适配器类,其代码如下:
-
public class ImgaePagerAdapter extends PagerAdapter {
-
-
ImageView[] mImageViews;
-
-
public ImgaePagerAdapter(ImageView[] mImageViews) {
-
this.mImageViews = mImageViews;
-
}
-
-
@Override
-
public int getCount() {
-
return Integer.MAX_VALUE;
-
}
-
-
@Override
-
public boolean isViewFromObject(View arg0, Object arg1) {
-
return arg0 == arg1;
-
}
-
-
@Override
-
public void destroyItem(View container, int position, Object object) {
-
-
((ViewPager) container).removeView(mImageViews[position
-
% mImageViews.length]);
-
-
}
-
-
-
-
-
@Override
-
public Object instantiateItem(View container, int position) {
-
((ViewPager) container).addView(mImageViews[position
-
% mImageViews.length], 0);
-
return mImageViews[position % mImageViews.length];
-
}
-
-
}
循环图片的代码主要放在了instantiateItem中,该事件负责将图片添加到容器中,并返回该图片视图,并且每次返回的图片为当前的位置和图片的总长度取余数,通过取余数从而判断是否进行循环。
在Fragment中调用如下的代码对数据适配器的绑定
viewPager.setAdapter(new ImgaePagerAdapter(mImageViews));
viewPager.setOnPageChangeListener(this);
(3)控件
这里的列表控件用来显示精选衣服基本信息,使用图片加文字的组合方式,我们第一反应想到的是GridView控件,这个想法是对的;可是我们注意到“精选”菜单的整个布局是使用ScrollView控件来控制上下一起移动的,如果单纯使用GridView控件的话,GridView控件在ScrollView中会显示不正常,所以我们应当自定义GirdView让它不能滑动,并且适配ScrollView控件的大小。定义MyGridView控件:
-
public class ImgaePagerAdapter extends PagerAdapter {
-
-
ImageView[] mImageViews;
-
-
public ImgaePagerAdapter(ImageView[] mImageViews) {
-
this.mImageViews = mImageViews;
-
}
-
-
@Override
-
public int getCount() {
-
return Integer.MAX_VALUE;
-
}
-
-
@Override
-
public boolean isViewFromObject(View arg0, Object arg1) {
-
return arg0 == arg1;
-
}
-
-
@Override
-
public void destroyItem(View container, int position, Object object) {
-
-
((ViewPager) container).removeView(mImageViews[position
-
% mImageViews.length]);
-
-
}
-
-
-
-
-
@Override
-
public Object instantiateItem(View container, int position) {
-
((ViewPager) container).addView(mImageViews[position
-
% mImageViews.length], 0);
-
return mImageViews[position % mImageViews.length];
-
}
-
-
}
在绘制GridView控件大小的时候,通过设置MeasureSpec.AT_MOST参数来指定到想要控件高度,通过onMeasure事件来绘制GridView。在XML布局中引用<com.blog.mogujie.tool.MyGridView ../>,布局文件代码太长就不贴出来了,待会在后面提供代码下载链接。
然后再定义该GridView文件的适配器,代码如下,注意GridView的优化设置:
-
public class GrdoneAdapter extends BaseAdapter{
-
-
private Context mContext;
-
private List<GrdOneInfo> mGrdOneInfoList;
-
public GrdoneAdapter(Context mContext,List<GrdOneInfo> mGrdOneInfoList){
-
this.mContext=mContext;
-
this.mGrdOneInfoList=mGrdOneInfoList;
-
}
-
@Override
-
public int getCount() {
-
-
return mGrdOneInfoList.size();
-
}
-
-
@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) {
-
View view = convertView;
-
final ViewHolder holder;
-
if (convertView == null) {
-
view = ((Activity) mContext).getLayoutInflater().inflate(
-
R.layout.item_grd1, parent, false);
-
holder = new ViewHolder();
-
holder.image = (ImageView) view.findViewById(R.id.grdimage);
-
holder.brife= (TextView) view.findViewById(R.id.brife1);
-
holder.price= (TextView) view.findViewById(R.id.price);
-
holder.marks= (TextView) view.findViewById(R.id.marks);
-
view.setTag(holder);
-
} else {
-
holder = (ViewHolder) view.getTag();
-
}
-
holder.image.setImageResource(mGrdOneInfoList.get(position).imagePath);
-
if(mGrdOneInfoList.get(position).brife.length()>50){
-
holder.brife.setText(mGrdOneInfoList.get(position).brife.subSequence(0, 30)+"...");
-
}else{
-
holder.brife.setText(mGrdOneInfoList.get(position).brife);
-
}
-
holder.price.setText(mGrdOneInfoList.get(position).price);
-
holder.marks.setText(mGrdOneInfoList.get(position).marksNum);
-
return view;
-
}
-
-
static class ViewHolder{
-
ImageView image;
-
TextView brife;
-
TextView price;
-
TextView marks;
-
}
-
}
最终效果如下:

资源地址为点击打开链接,今天到这里。