转载请标明出处: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的完整代码点击下载
分享到:
相关推荐
高仿微信5.2.1主界面及消息提醒 高仿微信5.2.1主界面及消息提醒
用fragment+viewpager技术高仿微信5.2.1主界面
高仿微信5.2.1主界面及消息提醒(fragment+viewPager+BadgeView)
高仿微信5.2.1主界面图标和第三方jar包资源
高仿微信5.2.1页面,ViewPager+Fragment实现滑动效果
主要为大家详细介绍了Android高仿微信5.2.1主界面及消息提醒,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
聊天 腾讯 用户可进行语音聊天 现在用户比较多 只需要流量即可
微信5.2.1的源代码 个人研究 请勿用于商业用途
基于微信平台的校园通知小程序系统的设计与实现(源码 + 说明文档 + 演示视频) 第四章 系统设计 12 4.1系统功能设计 12 4.2 系统总体设计 13 4.2.1 系统流程图 13 4.2.2 数据流图 13 4.3 系统架构设计 14 4.4 ...
基于微信平台的鲜花销售微信小程序(源码 + 说明文档) 2系统相关技术 7 2.1 Java语言简介 7 2.2微信开发者工具 8 2.3 B/S架构 8 2.4 MySQL 介绍 8 2.5 SSM框架 8 3系统需求分析 10 3.1系统功能 10 3.2可行性研究 ...
基于微信平台的基于微信小程序的自习室预约系统(源码 + 说明文档 + 演示视频) 第四章 系统设计 11 4.1系统功能设计 11 4.2 系统总体设计 12 4.2.1 系统流程图 12 4.2.2 数据流图 12 4.3 系统架构设计 13 4.4 ...
Lua 5.2.1源码,其中带VS2005的解决方案和项目文件(更新版本的VS也能兼容)。在压缩包中的WinBuild中包含了VS2005构建用的文件和目录,可以将Lua核心库编译成动态库或静态库,可以生成Lua编译器和命令行解释器。
微信公众平台开发最佳实践的源代码,没有加密。微信公众平台开发最佳实践讲的很详细,图文并茂。 其目录如下: 前 言 第1章 微信公众平台介绍 1 1.1 微信及其两大平台 1 1.2 微信公众平台 2 1.2.1 功能 2 1.2.2...
joytokey5.2.1
基于微信平台的校园二手交易平台小程序(源码 + 说明文档) 2 关键技术介绍 3 2.1 SSM框架 3 2.2 Java技术及架构介绍 3 2.3 MYSQL数据库 3 2.4微信小程序框架 4 2.5 B/S架构 4 3 需求分析与可行性分析 5 3.1功能...
原先上传的不能用,更新一个codesmith5.2.1 破解 。安装完codesmith5.2.1后,直接安装CodeSmith.Licensing.exe就可以。 有人说不能用,所以不要分
5.1.2管理主界面 18 5.1.3文件信息管理 19 5.1.4用户管理 19 5.2 小程序端功能实现 20 5.2.1用户注册 20 5.2.2用户登录 21 5.2.3文件查看 22 5.2.4用户评论 24 第六章 系统测试 25 6.1 测试说明 25 6.2 功能测试 25 ...
sarscape5.2.1不支持哨兵1b数据的导入,双击安装补丁即可解决。