上一篇是微信的欢迎界面仿造,这里介绍的是欢迎页的下一步:微信主界面的粗仿。
一、设计
首先这个是Android的微信6.0版本,与苹果的样式还是不一样的,至于哪个好用就是仁者见仁了。
微信6.0版本的主界面构成,主要采用这两个控件:ViewPager+ActionBar。顶部,我们用ActionBar来实现,界面间的切换则用ViewPager来实现。
微信6.0版本的主界面有个比较特别的地方,就是界面滑动时,底部的按钮会有渐进的变色,我们这里采用的是两个图片(颜色不同,一张灰色,一张绿色)重叠的方式,在Viewpager滑动时,更改两张图片的alpha透明度的方式来实现该效果。
(这个主要是参考网上的一些资料,主要是这位博主的:http://blog.csdn.net/wangdong20/article/details/49798195)
二、实施
(1)主界面的头部,我们用ActionBar实现。ActionBar主要在于menu文件夹下menu.xml文件的配置。微信的头部有搜索以及一个加号。我们也实现类似效果。
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_search"
android:orderInCategory="100"
android:actionViewClass="android.widget.SearchView"
android:icon="@drawable/actionbar_search_icon"
android:showAsAction="ifRoom|collapseActionView"
android:title="@string/action_search"/>
<item
android:id="@+id/action_more"
android:orderInCategory="100"
android:actionProviderClass="com.example.custom.MyActionProvider"
android:icon="@drawable/actionbar_add_icon"
android:showAsAction="ifRoom"
android:title="@string/action_plus"/>
</menu>
搜索按钮,将actionViewClass设置为“android.widget.SearchView”即可。
加号,我们点击加号,会出现下面的一串menu按钮,这是一个Provider形式的选项。并且,加号下的menu是我们自定义的,因此,我们自定义了一个actionProviderClass。
actionProviderClass如下:

package com.example.custom;
import com.example.wechat.R;
import android.content.Context;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.MenuItem.OnMenuItemClickListener;
public class MyActionProvider extends ActionProvider{
Context context;
public MyActionProvider(Context context) {
super(context);
this.context=context;
}
@Override
public View onCreateActionView() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean hasSubMenu() {
return true;
}
@Override
public void onPrepareSubMenu(SubMenu subMenu) {
subMenu.clear();
subMenu.add(context.getString(R.string.plus_group_chat))
.setIcon(R.drawable.ofm_group_chat_icon)
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return true;
}
});
subMenu.add(context.getString(R.string.plus_add_friend))
.setIcon(R.drawable.ofm_add_icon)
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
});
subMenu.add(context.getString(R.string.plus_video_chat))
.setIcon(R.drawable.ofm_video_icon)
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
});
subMenu.add(context.getString(R.string.plus_scan))
.setIcon(R.drawable.ofm_qrcode_icon)
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
});
subMenu.add(context.getString(R.string.plus_take_photo))
.setIcon(R.drawable.ofm_camera_icon)
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
});
super.onPrepareSubMenu(subMenu);
}
}
为了防止ActionBar在某些手机或者机具上,不显示我们的provider,我们在代码中做了强制控制,用反射的形式设置了它的值:
private void setOverflowShowingAlways() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class
.getDeclaredField("sHasPermanentMenuKey");
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
} catch (Exception e) {
e.printStackTrace();
}
}
有关ActionBar大体如上。
(2)主界面中部的ViewPager。这个采用ViewPager+FragmentPagerAdapter适配来实现。微信的四个界面,都用fragment来实现。
private class MyFragmentPagerAdapter extends FragmentPagerAdapter{
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
return mList.get(arg0);
}
@Override
public int getCount() {
return mList.size();
}
}
(3)主界面下部。这个为了实现图标透明度的变换,用了2*4个图片+2*4个TextView。看着比较复杂,主要还是在界面的xml配置上。
主界面的XML配置文件如下:
<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.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
></android.support.v4.view.ViewPager>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#fff"
android:orientation="vertical" >
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCC" />
<LinearLayout
android:baselineAligned="false"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:onClick="wechatClick">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/wechat_icon_select"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/wechat_select" />
<ImageView
android:id="@+id/wechat_icon_normal"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/wechat_normal" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/wechat_text_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#51C650"
/>
<TextView
android:id="@+id/wechat_text_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#999999"
/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:onClick="contactClick">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/contact_icon_select"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/contact_select" />
<ImageView
android:id="@+id/contact_icon_normal"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/contact_normal" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/contact_text_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="联系人"
android:textColor="#51C650"
/>
<TextView
android:id="@+id/contact_text_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="联系人"
android:textColor="#999999"
/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:onClick="findClick">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/find_icon_select"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/find_select" />
<ImageView
android:id="@+id/find_icon_normal"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/find_normal" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/find_text_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发现"
android:textColor="#51C650"
/>
<TextView
android:id="@+id/find_text_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发现"
android:textColor="#999999"/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:onClick="meClick">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/me_icon_select"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/me_select" />
<ImageView
android:id="@+id/me_icon_normal"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/me_normal" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/me_text_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我"
android:textColor="#51C650"/>
<TextView
android:id="@+id/me_text_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我"
android:textColor="#999999"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
这里贴上主界面的所有代码:
package com.example.wechat;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
private ViewPager pager;
private List<Fragment> mList;
private List<ImageView> mListImageViews;
private List<TextView> mListTextViews;
private FragmentPagerAdapter adapter;
private ImageView wechatIconSelect;
private ImageView wechatIconNormal;
private ImageView contactIconSelect;
private ImageView contactIconNormal;
private ImageView findIconSelect;
private ImageView findIconNormal;
private ImageView meIconSelect;
private ImageView meIconNormal;
private TextView wechatTextSelect;
private TextView wechatTextNormal;
private TextView contactTextSelect;
private TextView contactTextNormal;
private TextView findTextSelect;
private TextView findTextNormal;
private TextView meTextSelect;
private TextView meTextNormal;
private final int WECHAT_INDEX = 0; // 微信菜单索引
private final int CONTACT_INDEX = 1; // 联系人菜单索引
private final int FIND_INDEX = 2; // 发现菜单索引
private final int ME_INDEX = 3; // 我菜单索引
private int curIndex; // 当前菜单索引
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setOverflowShowingAlways();
initView();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (Exception e) {
}
}
}
return super.onMenuOpened(featureId, menu);
}
private void setOverflowShowingAlways() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class
.getDeclaredField("sHasPermanentMenuKey");
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
} catch (Exception e) {
e.printStackTrace();
}
}
private void initView(){
wechatIconSelect = (ImageView) findViewById(R.id.wechat_icon_select);
wechatIconNormal = (ImageView) findViewById(R.id.wechat_icon_normal);
contactIconSelect = (ImageView) findViewById(R.id.contact_icon_select);
contactIconNormal = (ImageView) findViewById(R.id.contact_icon_normal);
findIconSelect = (ImageView) findViewById(R.id.find_icon_select);
findIconNormal = (ImageView) findViewById(R.id.find_icon_normal);
meIconSelect = (ImageView) findViewById(R.id.me_icon_select);
meIconNormal = (ImageView) findViewById(R.id.me_icon_normal);
mListImageViews=new ArrayList<ImageView>();
mListImageViews.add(wechatIconNormal);
mListImageViews.add(wechatIconSelect);
mListImageViews.add(contactIconNormal);
mListImageViews.add(contactIconSelect);
mListImageViews.add(findIconNormal);
mListImageViews.add(findIconSelect);
mListImageViews.add(meIconNormal);
mListImageViews.add(meIconSelect);
wechatTextSelect = (TextView) findViewById(R.id.wechat_text_select);
wechatTextNormal = (TextView) findViewById(R.id.wechat_text_normal);
contactTextSelect = (TextView) findViewById(R.id.contact_text_select);
contactTextNormal = (TextView) findViewById(R.id.contact_text_normal);
findTextSelect = (TextView) findViewById(R.id.find_text_select);
findTextNormal = (TextView) findViewById(R.id.find_text_normal);
meTextSelect = (TextView) findViewById(R.id.me_text_select);
meTextNormal = (TextView) findViewById(R.id.me_text_normal);
mListTextViews=new ArrayList<TextView>();
mListTextViews.add(wechatTextNormal);
mListTextViews.add(wechatTextSelect);
mListTextViews.add(contactTextNormal);
mListTextViews.add(contactTextSelect);
mListTextViews.add(findTextNormal);
mListTextViews.add(findTextSelect);
mListTextViews.add(meTextNormal);
mListTextViews.add(meTextSelect);
pager=(ViewPager)findViewById(R.id.pager);
mList=new ArrayList<Fragment>();
mList.add(new Fragment1());
mList.add(new Fragment2());
mList.add(new Fragment3());
mList.add(new Fragment4());
adapter=new MyFragmentPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
pager.setOnPageChangeListener(new MyOnPageChangeListener());
//默认情况下,第一个按钮默认选中,显示绿色
wechatIconNormal.setAlpha(0f);
wechatTextNormal.setAlpha(0f);
//默认情况下,其他按钮默认不选中,显示灰色
contactIconSelect.setAlpha(0f);
contactTextSelect.setAlpha(0f);
findIconSelect.setAlpha(0f);
findTextSelect.setAlpha(0f);
meIconSelect.setAlpha(0f);
meTextSelect.setAlpha(0f);
}
//点击事件
public void wechatClick(View view){
if(curIndex!=WECHAT_INDEX){
colorChange(curIndex, WECHAT_INDEX, 1);
pager.setCurrentItem(WECHAT_INDEX,false);
}
}
//点击事件
public void contactClick(View view){
if(curIndex!=CONTACT_INDEX){
colorChange(curIndex, CONTACT_INDEX, 1);
pager.setCurrentItem(CONTACT_INDEX,false);
}
}
//点击事件
public void findClick(View view){
if(curIndex!=FIND_INDEX){
colorChange(curIndex, FIND_INDEX, 1);
pager.setCurrentItem(FIND_INDEX,false);
}
}
//点击事件
public void meClick(View view){
if(curIndex!=ME_INDEX){
colorChange(curIndex, ME_INDEX, 1);
pager.setCurrentItem(ME_INDEX,false);
}
}
//适配
private class MyFragmentPagerAdapter extends FragmentPagerAdapter{
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
return mList.get(arg0);
}
@Override
public int getCount() {
return mList.size();
}
}
//ViewPager界面变化事件
private class MyOnPageChangeListener implements OnPageChangeListener{
@Override
public void onPageScrollStateChanged(int arg0) {
Log.i("color", "ScrollState:"+arg0);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.i("color", "position:"+position+" positionOffset:"+positionOffset+" positionOffsetPixels:"+positionOffsetPixels);
if(positionOffset>0){
colorChange(position,position+1,positionOffset);
}
}
@Override
public void onPageSelected(int position) {
Log.i("color", "PageSelected:"+position);
curIndex = position;
}
}
/**
*
* @param srcIndex 失去焦点的索引
* @param destIndex 选中的索引
* @param ratio 透明的比例
*/
private void colorChange(int srcIndex, int destIndex, float ratio) {
mListImageViews.get(srcIndex * 2).setAlpha(ratio);
mListImageViews.get(srcIndex * 2 + 1).setAlpha(1 - ratio);
mListImageViews.get(destIndex * 2).setAlpha(1 - ratio);
mListImageViews.get(destIndex * 2 + 1).setAlpha(ratio);
mListTextViews.get(srcIndex * 2).setAlpha(ratio);
mListTextViews.get(srcIndex * 2 + 1).setAlpha(1 - ratio);
mListTextViews.get(destIndex * 2).setAlpha(1 - ratio);
mListTextViews.get(destIndex * 2 + 1).setAlpha(ratio);
}
}
微信主界面的图标变色,主要引用这位博主(http://blog.csdn.net/wangdong20/article/details/49798195)写的。简单粗暴。
至此,微信主界面样式已经完成。
三、源码
http://download.csdn.net/detail/yangzhaomuma/9553259