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



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

  • 相关阅读:
    trackr: An AngularJS app with a Java 8 backend – Part III
    trackr: An AngularJS app with a Java 8 backend – Part II
    21. Wireless tools (无线工具 5个)
    20. Web proxies (网页代理 4个)
    19. Rootkit detectors (隐形工具包检测器 5个)
    18. Fuzzers (模糊测试器 4个)
    16. Antimalware (反病毒 3个)
    17. Debuggers (调试器 5个)
    15. Password auditing (密码审核 12个)
    14. Encryption tools (加密工具 8个)
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4924959.html
Copyright © 2011-2022 走看看