高仿微信5.2.1主界面架构 包含消息通知

xiaoxiao2021-02-28  41

转载请标明出处:http://blog.csdn.NET/lmj623565791/article/details/25708045

一哥们去新疆前给了我个任务,就是整这东西,哥们回来了,赶紧做了个,哈哈,可惜没给我带切糕。

新版微信的效果,一眼看上去准备用ViewpagerIndicator来实现,但是需要在Indicator的后面添加消息通知(BadgeView),可惜没有办法自定义Indicator,最后还是自己写了个实现。

主结构:ViewPager和FragmentPagerAdapter

效果图:

1、主布局文件

[html] view plain copy print ? <?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:background=“#eee”      android:orientation=“vertical” >            <include layout=“@layout/top1”/>      <include layout=“@layout/top2”/>        <android.support.v4.view.ViewPager          android:id=“@+id/id_viewpager”          android:layout_width=“fill_parent”          android:layout_height=“0dp”          android:layout_weight=“1” >      </android.support.v4.view.ViewPager>      </LinearLayout>   <?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:background="#eee" android:orientation="vertical" > <include layout="@layout/top1"/> <include layout="@layout/top2"/> <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" > </android.support.v4.view.ViewPager> </LinearLayout> 2、top2.xml

[html] view plain copy print ? <?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=“wrap_content”      android:orientation=“vertical” >        <LinearLayout          android:id=“@+id/lllayout”          android:layout_width=“match_parent”          android:layout_height=“wrap_content”          android:orientation=“horizontal” >            <LinearLayout              android:id=“@+id/id_tab_liaotian_ly”              android:layout_width=“match_parent”              android:layout_height=“wrap_content”              android:layout_weight=“1”              android:background=“@drawable/guide_round”              android:gravity=“center”              android:orientation=“horizontal”              android:padding=“10dip” >                <TextView                  android:id=“@+id/id_liaotian”                  android:layout_width=“wrap_content”                  android:layout_height=“wrap_content”                  android:gravity=“center”                  android:text=“聊天”                  android:textColor=“@color/green”                  android:textSize=“15dip” />          </LinearLayout>            <LinearLayout              android:id=“@+id/id_tab_faxian_ly”              android:layout_width=“match_parent”              android:layout_height=“wrap_content”              android:layout_weight=“1”              android:background=“@drawable/guide_round”              android:clickable=“true”              android:gravity=“center”               android:orientation=“horizontal”              android:padding=“10dip”              android:saveEnabled=“false” >                <TextView                  android:id=“@+id/id_faxian”                  android:layout_width=“wrap_content”                  android:layout_height=“wrap_content”                  android:gravity=“center”                  android:text=“发现”                  android:textColor=“@color/black”                  android:textSize=“15dip” />          </LinearLayout>            <LinearLayout              android:id=“@+id/id_tab_tongxunlu_ly”              android:layout_width=“match_parent”              android:layout_height=“wrap_content”              android:layout_weight=“1”              android:background=“@drawable/guide_round”              android:focusable=“false”              android:gravity=“center”               android:orientation=“horizontal”              android:padding=“10dip” >                <TextView                  android:id=“@+id/id_tongxunlu”                  android:layout_width=“wrap_content”                  android:layout_height=“wrap_content”                  android:gravity=“center”                  android:text=“通讯录”                  android:textColor=“@color/black”                  android:textSize=“15dip” />          </LinearLayout>      </LinearLayout>        <ImageView          android:id=“@+id/id_tab_line”          android:layout_width=“200dp”          android:layout_height=“wrap_content”          android:background=“@drawable/vpi__tab_selected_pressed_holo” >      </ImageView>    </LinearLayout>   <?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="wrap_content" android:orientation="vertical" > <LinearLayout android:id="@+id/lllayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:id="@+id/id_tab_liaotian_ly" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/guide_round" android:gravity="center" android:orientation="horizontal" android:padding="10dip" > <TextView android:id="@+id/id_liaotian" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="聊天" android:textColor="@color/green" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:id="@+id/id_tab_faxian_ly" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/guide_round" android:clickable="true" android:gravity="center" android:orientation="horizontal" android:padding="10dip" android:saveEnabled="false" > <TextView android:id="@+id/id_faxian" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="发现" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:id="@+id/id_tab_tongxunlu_ly" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/guide_round" android:focusable="false" android:gravity="center" android:orientation="horizontal" android:padding="10dip" > <TextView android:id="@+id/id_tongxunlu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="通讯录" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/id_tab_line" android:layout_width="200dp" android:layout_height="wrap_content" android:background="@drawable/vpi__tab_selected_pressed_holo" > </ImageView> </LinearLayout> 这个布局也很简单,在布局中加入了一个ImageView,这个会在程序中动态计算宽度,作为Tab的引导线。

3、主程序

[java] view plain copy print ? package com.example.mainframework04;    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.FragmentPagerAdapter;  import android.support.v4.view.ViewPager;  import android.support.v4.view.ViewPager.OnPageChangeListener;  import android.util.DisplayMetrics;  import android.util.Log;  import android.view.Gravity;  import android.widget.FrameLayout;  import android.widget.FrameLayout.LayoutParams;  import android.widget.ImageView;  import android.widget.LinearLayout;  import android.widget.TextView;    import com.jauker.widget.BadgeView;    public class MainActivity extends FragmentActivity  {      private ViewPager mViewPager;      private FragmentPagerAdapter mAdapter;      private List<Fragment> mFragments = new ArrayList<Fragment>();        /**      * 顶部三个LinearLayout      */      private LinearLayout mTabLiaotian;      private LinearLayout mTabFaxian;      private LinearLayout mTabTongxunlun;        /**      * 顶部的三个TextView      */      private TextView mLiaotian;      private TextView mFaxian;      private TextView mTongxunlu;        /**      * 分别为每个TabIndicator创建一个BadgeView      */      private BadgeView mBadgeViewforLiaotian;      private BadgeView mBadgeViewforFaxian;      private BadgeView mBadgeViewforTongxunlu;        /**      * Tab的那个引导线      */      private ImageView mTabLine;      /**      * ViewPager的当前选中页      */      private int currentIndex;      /**      * 屏幕的宽度      */      private int screenWidth;        @Override      protected void onCreate(Bundle savedInstanceState)      {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);            mViewPager = (ViewPager) findViewById(R.id.id_viewpager);            initView();            initTabLine();            /**          * 初始化Adapter          */          mAdapter = new FragmentPagerAdapter(getSupportFragmentManager())          {              @Override              public int getCount()              {                  return mFragments.size();              }                @Override              public Fragment getItem(int arg0)              {                  return mFragments.get(arg0);              }          };            mViewPager.setAdapter(mAdapter);            /**          * 设置监听          */          mViewPager.setOnPageChangeListener(new OnPageChangeListener()          {                @Override              public void onPageSelected(int position)              {                  // 重置所有TextView的字体颜色                  resetTextView();                  switch (position)                  {                  case 0:                      /**                      * 设置消息通知                      */                      mTabLiaotian.removeView(mBadgeViewforLiaotian);                      mBadgeViewforLiaotian.setBadgeCount(5);                      mTabLiaotian.addView(mBadgeViewforLiaotian);                      mLiaotian.setTextColor(getResources().getColor(R.color.green));                      break;                  case 1:                      /**                      * 设置消息通知                      */                      mFaxian.setTextColor(getResources().getColor(R.color.green));                      mTabFaxian.removeView(mBadgeViewforFaxian);                      mBadgeViewforFaxian.setBadgeCount(15);                      mTabFaxian.addView(mBadgeViewforFaxian);                      break;                  case 2:                      mTongxunlu.setTextColor(getResources().getColor(R.color.green));                        break;                  }                    currentIndex = position;              }                @Override              public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)              {                  /**                  * 利用position和currentIndex判断用户的操作是哪一页往哪一页滑动                  * 然后改变根据positionOffset动态改变TabLine的leftMargin                  */                  if (currentIndex == 0 && position == 0)// 0->1                  {                      LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine                              .getLayoutParams();                      lp.leftMargin = (int) (positionOffset * (screenWidth * 1.0 / 3) + currentIndex * (screenWidth / 3));                      mTabLine.setLayoutParams(lp);                    } else if (currentIndex == 1 && position == 0// 1->0                  {                      LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine                              .getLayoutParams();                      lp.leftMargin = (int) (-(1 - positionOffset) * (screenWidth * 1.0 / 3) + currentIndex                              * (screenWidth / 3));                      mTabLine.setLayoutParams(lp);                    } else if (currentIndex == 1 && position == 1// 1->2                  {                      LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine                              .getLayoutParams();                      lp.leftMargin = (int) (positionOffset * (screenWidth * 1.0 / 3) + currentIndex * (screenWidth / 3));                      mTabLine.setLayoutParams(lp);                  } else if (currentIndex == 2 && position == 1// 2->1                  {                      LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine                              .getLayoutParams();                      lp.leftMargin = (int) (-(1 - positionOffset) * (screenWidth * 1.0 / 3) + currentIndex                              * (screenWidth / 3));                      mTabLine.setLayoutParams(lp);                    }                }                @Override              public void onPageScrollStateChanged(int state)              {              }          });            mViewPager.setCurrentItem(1);        }        /**      * 根据屏幕的宽度,初始化引导线的宽度      */      private void initTabLine()      {          mTabLine = (ImageView) findViewById(R.id.id_tab_line);          DisplayMetrics outMetrics = new DisplayMetrics();          getWindow().getWindowManager().getDefaultDisplay().getMetrics(outMetrics);          screenWidth = outMetrics.widthPixels;          LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine.getLayoutParams();          lp.width = screenWidth / 3;          mTabLine.setLayoutParams(lp);      }        /**      * 重置颜色      */      protected void resetTextView()      {          mLiaotian.setTextColor(getResources().getColor(R.color.black));          mFaxian.setTextColor(getResources().getColor(R.color.black));          mTongxunlu.setTextColor(getResources().getColor(R.color.black));      }        /**      * 初始化控件,初始化Fragment      */      private void initView()      {            mTabLiaotian = (LinearLayout) findViewById(R.id.id_tab_liaotian_ly);          mTabFaxian = (LinearLayout) findViewById(R.id.id_tab_faxian_ly);          mTabTongxunlun = (LinearLayout) findViewById(R.id.id_tab_tongxunlu_ly);            mLiaotian = (TextView) findViewById(R.id.id_liaotian);          mFaxian = (TextView) findViewById(R.id.id_faxian);          mTongxunlu = (TextView) findViewById(R.id.id_tongxunlu);            MainTab01 tab01 = new MainTab01();          MainTab02 tab02 = new MainTab02();          MainTab03 tab03 = new MainTab03();          mFragments.add(tab01);          mFragments.add(tab02);          mFragments.add(tab03);            mBadgeViewforFaxian = new BadgeView(this);          mBadgeViewforLiaotian = new BadgeView(this);          mBadgeViewforTongxunlu = new BadgeView(this);      }  }   package com.example.mainframework04; 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.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; import android.widget.FrameLayout; import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.jauker.widget.BadgeView; public class MainActivity extends FragmentActivity { private ViewPager mViewPager; private FragmentPagerAdapter mAdapter; private List<Fragment> mFragments = new ArrayList<Fragment>(); /** * 顶部三个LinearLayout */ private LinearLayout mTabLiaotian; private LinearLayout mTabFaxian; private LinearLayout mTabTongxunlun; /** * 顶部的三个TextView */ private TextView mLiaotian; private TextView mFaxian; private TextView mTongxunlu; /** * 分别为每个TabIndicator创建一个BadgeView */ private BadgeView mBadgeViewforLiaotian; private BadgeView mBadgeViewforFaxian; private BadgeView mBadgeViewforTongxunlu; /** * Tab的那个引导线 */ private ImageView mTabLine; /** * ViewPager的当前选中页 */ private int currentIndex; /** * 屏幕的宽度 */ private int screenWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.id_viewpager); initView(); initTabLine(); /** * 初始化Adapter */ mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public int getCount() { return mFragments.size(); } @Override public Fragment getItem(int arg0) { return mFragments.get(arg0); } }; mViewPager.setAdapter(mAdapter); /** * 设置监听 */ mViewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { // 重置所有TextView的字体颜色 resetTextView(); switch (position) { case 0: /** * 设置消息通知 */ mTabLiaotian.removeView(mBadgeViewforLiaotian); mBadgeViewforLiaotian.setBadgeCount(5); mTabLiaotian.addView(mBadgeViewforLiaotian); mLiaotian.setTextColor(getResources().getColor(R.color.green)); break; case 1: /** * 设置消息通知 */ mFaxian.setTextColor(getResources().getColor(R.color.green)); mTabFaxian.removeView(mBadgeViewforFaxian); mBadgeViewforFaxian.setBadgeCount(15); mTabFaxian.addView(mBadgeViewforFaxian); break; case 2: mTongxunlu.setTextColor(getResources().getColor(R.color.green)); break; } currentIndex = position; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { /** * 利用position和currentIndex判断用户的操作是哪一页往哪一页滑动 * 然后改变根据positionOffset动态改变TabLine的leftMargin */ if (currentIndex == 0 && position == 0)// 0->1 { LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine .getLayoutParams(); lp.leftMargin = (int) (positionOffset * (screenWidth * 1.0 / 3) + currentIndex * (screenWidth / 3)); mTabLine.setLayoutParams(lp); } else if (currentIndex == 1 && position == 0) // 1->0 { LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine .getLayoutParams(); lp.leftMargin = (int) (-(1 - positionOffset) * (screenWidth * 1.0 / 3) + currentIndex * (screenWidth / 3)); mTabLine.setLayoutParams(lp); } else if (currentIndex == 1 && position == 1) // 1->2 { LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine .getLayoutParams(); lp.leftMargin = (int) (positionOffset * (screenWidth * 1.0 / 3) + currentIndex * (screenWidth / 3)); mTabLine.setLayoutParams(lp); } else if (currentIndex == 2 && position == 1) // 2->1 { LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine .getLayoutParams(); lp.leftMargin = (int) (-(1 - positionOffset) * (screenWidth * 1.0 / 3) + currentIndex * (screenWidth / 3)); mTabLine.setLayoutParams(lp); } } @Override public void onPageScrollStateChanged(int state) { } }); mViewPager.setCurrentItem(1); } /** * 根据屏幕的宽度,初始化引导线的宽度 */ private void initTabLine() { mTabLine = (ImageView) findViewById(R.id.id_tab_line); DisplayMetrics outMetrics = new DisplayMetrics(); getWindow().getWindowManager().getDefaultDisplay().getMetrics(outMetrics); screenWidth = outMetrics.widthPixels; LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabLine.getLayoutParams(); lp.width = screenWidth / 3; mTabLine.setLayoutParams(lp); } /** * 重置颜色 */ protected void resetTextView() { mLiaotian.setTextColor(getResources().getColor(R.color.black)); mFaxian.setTextColor(getResources().getColor(R.color.black)); mTongxunlu.setTextColor(getResources().getColor(R.color.black)); } /** * 初始化控件,初始化Fragment */ private void initView() { mTabLiaotian = (LinearLayout) findViewById(R.id.id_tab_liaotian_ly); mTabFaxian = (LinearLayout) findViewById(R.id.id_tab_faxian_ly); mTabTongxunlun = (LinearLayout) findViewById(R.id.id_tab_tongxunlu_ly); mLiaotian = (TextView) findViewById(R.id.id_liaotian); mFaxian = (TextView) findViewById(R.id.id_faxian); mTongxunlu = (TextView) findViewById(R.id.id_tongxunlu); MainTab01 tab01 = new MainTab01(); MainTab02 tab02 = new MainTab02(); MainTab03 tab03 = new MainTab03(); mFragments.add(tab01); mFragments.add(tab02); mFragments.add(tab03); mBadgeViewforFaxian = new BadgeView(this); mBadgeViewforLiaotian = new BadgeView(this); mBadgeViewforTongxunlu = new BadgeView(this); } } 主要就是为ViewPager设置FragmentPagerAdapter,然后添加切换的监听,生成BadgeView,这里没有使用BadgeView.setTargetView(targetView),因为我希望通知显示在文本的后面,setTargetView可能只能设置显示位置为目标控件的内部位置。

再次就是TabLine的跟随手指的效果,首先会根据Tab页的数量为TabLine设置宽度,然后在onPageScrolled中根据position,positionOffset,currentIndex,判断用户当前手指滑动的方向,然后根据positionOffset这个百分比乘以TabLine的宽度,动态设置TabLine的leftMargin实现跟随手指移动的效果。

4、每个Fragment的代码

[java] view plain copy print ? package com.example.mainframework04;    import android.os.Bundle;  import android.support.v4.app.Fragment;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;    public class MainTab01 extends Fragment  {        @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)      {          return  inflater.inflate(R.layout.main_tab_01, container, false);            }    }   package com.example.mainframework04; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class MainTab01 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.main_tab_01, container, false); } } 3个标签页基本一致,不重复贴了。

[html] view plain copy print ? <?xml version=“1.0” encoding=“utf-8”?>  <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”      android:id=“@+id/ly_main_weixin”      android:layout_width=“fill_parent”      android:layout_height=“fill_parent”      android:background=“#fcfcfc”      android:orientation=“vertical” >        <TextView           android:layout_width=“fill_parent”          android:layout_height=“0dp”          android:layout_weight=“1”          android:gravity=“center”          android:text=“this is first tab !”          android:textColor=“#000000”          android:textSize=“30sp”          />    </LinearLayout>   <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ly_main_weixin" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#fcfcfc" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="this is first tab !" android:textColor="#000000" android:textSize="30sp" /> </LinearLayout> Fragment的布局文件,同样三个基本一致。

好了,结束,看起来挺复杂,实现起来还可以。代码写得比较仓促,有啥不足地方请指出来。最后求留言,求赞~

源码点击下载

包含BadgeView的完整代码点击下载

转载请注明原文地址: https://www.6miu.com/read-35898.html

最新回复(0)