Android仿新版微信主界面(使用android-support-v7兼容包,兼容2.2及其以上版本)

来源:互联网 发布:什么是移动数据流量 编辑:程序博客网 时间:2024/06/01 15:03

最近由于公司项目的界面需求,软件的主界面与微信的基本上差不多,于是花一点时间研究并实现了一下,用到了一些第三方的开源项目和android-support-v7兼容包,

主要用到了如下开源项目:

  1. PagerSlidingTabStrip (标签页的滑动)
  2. android-viewbadger (未读信息的提醒标识)
要说明的是PagerSlidingTabStrip我为了一些效果的需要自己作了一些改进和扩展,不然是无法达到所需的效果的,直接上效果图吧。

这里讲解一下标签的滑动,PagerSlidingTabStrip得到viewpager里的fragment的数量,获得屏幕的宽度,然后根据标签的数量来计算每个indicator的平均长度,当页面滑动时,根据当前页面的索引位置来获得对应的子控件,并条用scrollTo方法来滑动对应的位置,indicator的结构如图所示。

Textview用来显示标题的文字,后后面的view主要是用来显示未读信息的数量,因为BadgeView需要一个载体来显示信息。

MainActiivty.java的主要代码:

package com.example.mymicromsgdemo;import java.util.ArrayList;import java.util.List;import java.util.Locale;import android.content.Context;import android.graphics.Bitmap;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.os.AsyncTask;import android.os.Bundle;import android.os.SystemClock;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBarActivity;import android.view.Gravity;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.PopupWindow;import android.widget.TextView;import com.example.mymicromsgdemo.util.SystemUtil;import com.example.mymicromsgdemo.view.BadgeView;import com.example.mymicromsgdemo.view.PagerSlidingTabStrip;public class MainActivity extends ActionBarActivity {private Context mContext;private static String[] contentLables;private static int[] homeMenuPlusRes = { R.drawable.ic_launcher, R.drawable.ic_launcher,R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher };private static int[] menu_popup_more_res = { R.drawable.ic_launcher, R.drawable.ic_launcher };private static String[] menu_popup_plus_title = { "发起群聊", "添加朋友", "视频聊天", "扫一扫", "拍照" };private static String[] menu_popup_more_title = { "张三", "设置" };public static int CONTENT_HEIGHT = 0;private PopupWindow mPopupWindowAdd;private PopupWindow mPopupWindowMore;private View popupAddParent;private View popupMoreParent;private PagerSlidingTabStrip indicator;MyFragmentPagerAdapter adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = this;ActionBar actionBar = getSupportActionBar();actionBar.setTitle("微信");contentLables = getResources().getStringArray(R.array.home_function_lable);adapter = new MyFragmentPagerAdapter(getSupportFragmentManager());ViewPager pager = (ViewPager) findViewById(R.id.pager);pager.setAdapter(adapter);indicator = (PagerSlidingTabStrip) findViewById(R.id.indicator);indicator.setViewPager(pager);new LoadDataTAsk().execute();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {MenuInflater menuInflater = getMenuInflater();menuInflater.inflate(R.menu.menu_home, menu);return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.action_search: //搜索//openSearch();break;case R.id.action_add: //添加if (popupAddParent == null) {popupAddParent = findViewById(R.id.action_add);}showAddPopupWindow(popupAddParent);break;case R.id.action_more: //更多if (popupMoreParent == null) {popupMoreParent = findViewById(R.id.action_more);}showMorePopupWindow(popupMoreParent);break;default:break;}return super.onOptionsItemSelected(item);}/** * 初始化右上角菜单的资源 * @param resIds 图标资源数组 * @param titles 菜单标题数组 * @return 菜单列表 */private List<MenuPopupItem> initMenus(int[] resIds, String[] titles) {List<MenuPopupItem> list = new ArrayList<MenuPopupItem>();int len = titles.length;for (int i = 0; i < len; i++) {MenuPopupItem item = new MenuPopupItem(mContext.getResources().getDrawable(resIds[i]), titles[i]);list.add(item);}return list;}/** * 创建并显示“添加”的popup菜单 * @param parent */private void showAddPopupWindow(final View parent) {if (mPopupWindowAdd == null) {View view = LayoutInflater.from(mContext).inflate(R.layout.menu_home, null);ListView listView = (ListView) view.findViewById(R.id.lv_menu_popup);MemuPopupAdapter menuAddAdapter = new MemuPopupAdapter(mContext, initMenus(homeMenuPlusRes, menu_popup_plus_title));listView.setAdapter(menuAddAdapter);mPopupWindowAdd = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);initPopupWindow(mPopupWindowAdd);listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {togglePopupWindow(mPopupWindowAdd, parent);}});}togglePopupWindow(mPopupWindowAdd, parent);}/** * 创建并显示“更多”的popup菜单 * @param parent */private void showMorePopupWindow(final View parent) {if (mPopupWindowMore == null) {View view = LayoutInflater.from(mContext).inflate(R.layout.menu_home, null);ListView listView = (ListView) view.findViewById(R.id.lv_menu_popup);MemuPopupAdapter menuAddAdapter = new MemuPopupAdapter(mContext, initMenus(menu_popup_more_res, menu_popup_more_title));listView.setAdapter(menuAddAdapter);mPopupWindowMore = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);initPopupWindow(mPopupWindowMore);listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {togglePopupWindow(mPopupWindowMore, parent);}});}togglePopupWindow(mPopupWindowMore, parent);}/** * 初始化popupWindow的一些参数,主要用于菜单的显示方式 * @param window */private void initPopupWindow(PopupWindow window) {View view = window.getContentView();window.setWidth(SystemUtil.getViewSize(view)[0] + 35);window.setOutsideTouchable(true);window.setFocusable(true);window.update();window.setBackgroundDrawable(new BitmapDrawable(null, (Bitmap) null));window.setAnimationStyle(R.style.MenuPopupAnimStyle);}/** * 显示与消失popup菜单 * @param window * @param parent */private void togglePopupWindow(PopupWindow window, View parent) {if (window.isShowing()) {window.dismiss();} else {if (parent != null) {window.showAtLocation(parent, Gravity.TOP | Gravity.RIGHT, 5, SystemUtil.getStatusBarHeight(mContext) + SystemUtil.getActionBarHeight(mContext));}}}/** * 异步加载数据的线程 */class LoadDataTAsk extends AsyncTask<Void, Void, Void> {@Overrideprotected Void doInBackground(Void... params) {//1、在这里可以加载数据return null;}@Overrideprotected void onPostExecute(Void result) {//1、加载数据完毕后,更新界面//2、显示未读信息的提醒数量int count = contentLables.length;for(int i = 0; i < count; i++) {View view = indicator.getCurrentTargetView(i);if(i == 0) {//显示具体数量的提醒showBadgeView(mContext, view, 23);} else {showBadgeView(mContext, view, 0);}}}}private void showBadgeView(Context context, View target, int num) {BadgeView badgeView = new BadgeView(mContext, target);badgeView.setTextSize(10);badgeView.setGravity(Gravity.CENTER);        badgeView.setBadgePosition(BadgeView.POSITION_VERTICAL_LEFT);if(num == 0) {badgeView.setText("");badgeView.setBackgroundResource(R.drawable.main_tab_new_message_notify);} else {badgeView.setText(String.valueOf(num));badgeView.setBackgroundResource(R.drawable.g_unread_messages_bg);}badgeView.show();}/** * popup菜单的适配器 */class MemuPopupAdapter extends BaseAdapter {private Context context;private List<MenuPopupItem> list;public MemuPopupAdapter(Context context, List<MenuPopupItem> list) {super();this.context = context;this.list = list;}@Overridepublic int getCount() {return list.size();}@Overridepublic Object getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {MenuViewHolder holder = null;if (convertView == null) {holder = new MenuViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.item_menu_popu, parent, false);ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_menu_icon);TextView textView = (TextView) convertView.findViewById(R.id.tv_menu_title);holder.icon = imageView;holder.title = textView;convertView.setTag(holder);} else {holder = (MenuViewHolder) convertView.getTag();}MenuPopupItem item = list.get(position);Drawable icon = item.getIcon();String title = item.getTitle();if (icon == null) {holder.icon.setVisibility(View.GONE);} else {holder.icon.setImageDrawable(icon);}holder.title.setText(title);return convertView;}final class MenuViewHolder {ImageView icon;TextView title;}}class MyFragmentPagerAdapter extends FragmentPagerAdapter {public MyFragmentPagerAdapter(FragmentManager fm) {super(fm);}@Overridepublic Fragment getItem(int position) {return TestFragment.newInstance("测试内容" + (position + 1));}@Overridepublic CharSequence getPageTitle(int position) {return contentLables[position % contentLables.length].toUpperCase(Locale.getDefault());}@Overridepublic int getCount() {return contentLables.length;}}}
布局文件activity_main.xml的主要代码为:

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:psts="http://schemas.android.com/apk/res/com.example.mymicromsgdemo"    android:orientation="vertical"    android:layout_width="fill_parent"    android:background="#ffffff"    android:layout_height="fill_parent">             <com.example.mymicromsgdemo.view.PagerSlidingTabStrip         android:id="@+id/indicator"        android:layout_height="40dp"        android:layout_width="fill_parent"        psts:pstsDividerColor="@android:color/transparent"        psts:pstsUnderlineHeight="1dp"        psts:pstsIndicatorHeight="4dp"        psts:pstsIndicatorColor="@color/pager_tab_indicator_color"        psts:pstsSelectedTabTextColor="@color/pager_tab_indicator_color"        psts:pstsTabBackground="@android:color/transparent"        android:textSize="16sp"/>             <android.support.v4.view.ViewPager        android:id="@+id/pager"        android:layout_width="fill_parent"        android:layout_height="0dp"        android:layout_weight="1"        /></LinearLayout>

为了兼容Android2.X,本项目采用android-support-v7的兼容包来实现actionbar,当然,也有一些第三方的优秀的包可以做到,如大名鼎鼎的ActionBarSherlock。要在actionbar上弹出微信那样效果的效果,在4.X是很容易实现的,但为了兼容2.x,这里用普通的munu可能不好实现,自己暂时木有想到,有想到的朋友可以探讨一下,于是就使用了popupwindow来实现,主要的原理是在actionbar的菜单项中相应点击事件,然后来弹出菜单。

系统的菜单menu_home.xml源码如下。

<menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto" >    <item        android:id="@+id/action_search"        android:orderInCategory="100"        app:showAsAction="always"        android:title="搜索"        android:icon="@drawable/system_menu_search_normal" />        <item        android:id="@+id/action_add"        android:orderInCategory="101"        app:showAsAction="always"        android:title="添加"        android:icon="@drawable/system_menu_plus_normal"/>        <item        android:id="@+id/action_more"        android:orderInCategory="102"        app:showAsAction="always"        android:title="更多"        android:icon="@drawable/system_menu_more_normal" /></menu>

注意:这里xmlns:app="http://schemas.android.com/apk/res-auto"意思是使用support-v7的资源,不然在2.x是显示不出来的。


popupwindow的显示条用了window.showAtLocation方法,具体的位置是x轴距右5个像素,y轴是通过计算出来的,y=屏幕的高度-状态栏的高度-actionbar的高度,当然,也可以用showAsDropDown方法来显,大家可以自己试一下。

好了,大致的内容就是这些,大家有什么疑问或者文中有什么问题可以指正。

Email:huanghui6579@163.com

QQ:409384897



源码下载,点击这里

2 0