您的位置:首页 > 运维架构 > 网站架构

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

2014-11-30 22:12 435 查看
首先这是转的:

转载请标明出处:/article/1345565.html

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

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

主结构:ViewPager和FragmentPagerAdapter

效果图:



1、主布局文件

[html] view plaincopy





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





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





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 plaincopy





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 plaincopy





<?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的完整代码点击下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: