zoukankan      html  css  js  c++  java
  • 高仿微信5.2.1主界面架构 包含消息通知

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

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

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

    主结构:ViewPager和FragmentPagerAdapter

    效果图:

    1、主布局文件

    <?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

    <?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、主程序

    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的代码

    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个标签页基本一致,不重复贴了。

    <?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的完整代码点击下载



    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    树莓派服务器搭建
    设计模式之装饰者模式
    设计模式之建造者模式
    Java IO
    设计模式之抽象工厂模式
    常用排序算法(堆排序)
    Struts2框架简介和示例
    静态代理和利用反射形成的动态代理(JDK动态代理)
    常用排序算法(插入排序,快速排序,归并排序,堆排序)
    设计模式之简单工厂和工厂方法模式
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4924959.html
Copyright © 2011-2022 走看看