public class MyIndicator extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
private ViewPager mViewPager;
private LinearLayout myLinearLayout; /**
* 我们实现了ViewPager.OnPageChangeListener接口,因为我们要监听ViewPager的滑页行为,从而去改变导航栏的状态
* 所以我们也可以看到,MyIndicator持有ViewPager的引用,如果我们还想要监听ViewPager怎么办呢?
* 这里我为MyIndicator提供了一个接口,与OnPageChangeListener方法一样调用
**/ MyOnPageChangeListener mListener; private interface MyOnPageChangeListener {
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); void onPageSelected(int position); void onPageScrollStateChanged(int state);
} private int oldSelected; //为了让TextView能点击,我为每个TextView都设置了OnClickListener,
//就是获得目标标题栏的index,然后调用setCurrentItem()就可以了,这样就实现了点击滑动的效果,点击标题栏,Viewpager也会跟着翻页。
private final OnClickListener mTabClickListener = new OnClickListener() {
public void onClick(View view) {
MyTabView tabView = (MyTabView) view;
oldSelected = mViewPager.getCurrentItem();
final int newSelected = tabView.index;
setCurrentItem(newSelected);
}
}; public MyIndicator(Context context) {
super(context);
init(context);
} public MyIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
} public MyIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
} private void init(Context mcontext) {
setHorizontalScrollBarEnabled(false);//隐藏自带的滚动条
//添加linearLayout
myLinearLayout = new LinearLayout(mcontext);
myLinearLayout.setOrientation(LinearLayout.HORIZONTAL); addView(myLinearLayout, new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
} public void setViewPager(ViewPager viewPager) {
setViewPager(viewPager, 0);
} @SuppressWarnings("deprecation")
public void setViewPager(ViewPager viewPager, int initPos) {
if (mViewPager == viewPager) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
final PagerAdapter adapter = viewPager.getAdapter();
if (adapter == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = viewPager;
viewPager.setOnPageChangeListener(this);
notifyDataSetChanged();
setCurrentItem(initPos);
} private void notifyDataSetChanged() {
myLinearLayout.removeAllViews();
PagerAdapter mAdapter = mViewPager.getAdapter();
int count = mAdapter.getCount();
for (int i = 0; i < count; i++) {
addTab(i, mAdapter.getPageTitle(i));
}
requestLayout();
} /**
* 代码添加顶部的TextView
*
* @param index
* @param text
*/
private void addTab(int index, CharSequence text) {
MyTabView tabView = new MyTabView(getContext());
tabView.index = index;
tabView.setFocusable(true);
tabView.setOnClickListener(mTabClickListener);
tabView.setText(text);
tabView.setTextSize(22);
tabView.setTextColor(getContext().getResources().getColor(R.color.colorWhite));
tabView.setPadding(20, 0, 20, 0);
tabView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
PagerAdapter mAdapter = mViewPager.getAdapter();
int screenWidth = getResources().getDisplayMetrics().widthPixels;
if (mAdapter.getCount() <= 4) {
tabView.setWidth(screenWidth / mAdapter.getCount());
} else {
tabView.setWidth(screenWidth / 4);
} myLinearLayout.addView(tabView);
} /**
* 被选中的动画
*
* @param view
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
private void animation(View view) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f);
ObjectAnimator fade = ObjectAnimator.ofFloat(view, "alpha", 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(scaleX).with(scaleY).with(fade);
animSet.setDuration(500);
animSet.start();
} /**
* 没选中的动画
*
* @param view
*/
private void animation2(View view) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 0.8f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 0.8f);
ObjectAnimator fade = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(scaleX).with(scaleY).with(fade);
animSet.setDuration(500);
animSet.start();
} public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
int mSelectedTabIndex = item;
mViewPager.setCurrentItem(item); final int tabCount = myLinearLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {//遍历标题,改变选中的背景
final View child = myLinearLayout.getChildAt(i);
final boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animation(child);
animateToTab(item);//动画效果
} else {
animation2(child);
child.setBackgroundColor(Color.TRANSPARENT);
}
}
} private Runnable mTabSelector; private void animateToTab(final int position) {
final View tabView = myLinearLayout.getChildAt(position);
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;//计算要滑动到的位置
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector); //在主线程执行动画
} public void setMyOnPageChangeListener(MyOnPageChangeListener listener) {
mListener = listener;
} @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mListener != null)
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
} @Override
public void onPageSelected(int position) {
setCurrentItem(position);
if (mListener != null) mListener.onPageSelected(position);
} @Override
public void onPageScrollStateChanged(int state) {
if (mListener != null) mListener.onPageScrollStateChanged(state);
} }

使用:

<com.cqytjr.www.cheji.views.MyIndicator
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#c4c77f"/> <android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
 FragmentPagerAdapter adapter = new MyFragmentManager(getSupportFragmentManager(), content);

        pager = (ViewPager)findViewById(R.id.pager);
indicator = (MyIndicator)findViewById(R.id.indicator); pager.setAdapter(adapter);
indicator.setViewPager(pager);

Android仿今日头条手界面的更多相关文章

  1. Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)

    前言 上篇博客我们说到了今日头条频道管理的操作交互体验,我也介绍了2个GridView之间Item的相互移动.详情请參考:Android 仿今日头条频道管理(上)(GridView之间Item的移动和 ...

  2. android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码

    Android精选源码 android漂亮的加载效果 android各种 选择器 汇总源码 Android仿bilibili搜索框效果 Android记事本app.分类,涂鸦.添加图片或者其他附件 仿 ...

  3. Android 仿今日头条频道管理(上)(GridView之间Item的移动和拖拽)

    前言 常常逛今日头条.发现它的频道管理功能做的特别赞.交互体验很好.如图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fo ...

  4. Android仿今日头条和知乎等App顶部滑动导航实现代码分析及源码下载

    一.本文所涉及到的知识点 源码下载 二.目标 通过利用ViewPager+FragmentStatePagerAdapter+TabLayout 实现顶部滑动效果,如图: 三.知识点讲解 1.View ...

  5. [Android] Android 手机下 仿 今日头条 新闻客户端

    利用一个月的时间,自学了 Android 开发 ,为了检验学习成果,特意 开发了这个  仿 今日头条 新闻客户端 AppNews 包括图文新闻+视频新闻+图片新闻 预览演示如下: 功能说明: 1)底部 ...

  6. vue2.0仿今日头条开源项目

    vue-toutiao 这是用 vue.js 2.0 高仿 今日头条 的移动端项目,结合了原生app的部分功能以及网页版. 前言 本人是 今日头条 的重度用户,在学习vue.js过程中,在GitHub ...

  7. iOS仿今日头条滑动导航

    之前写了篇博客网易首页导航封装类.网易首页导航封装类优化,今天在前两个的基础上仿下今日头条. 1.网易首页导航封装类中主要解决了上面导航的ScrollView和下面的页面的ScrollView联动的问 ...

  8. vue 仿今日头条

    vue 仿今日头条 为了增加移动端项目的经验,近一周通过 vue 仿写今日头条,以下就项目实现过程中遇到的问题以及解决方法给出总结,有什么不正确的地方,恳请大家批评指正^ _ ^!,代码仓库地址为 g ...

  9. Android之仿今日头条顶部导航栏效果

    随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候像今日头条新闻客户端要显示的内容太多,而且又想在主界面全部显示出来,所以 ...

随机推荐

  1. win7 自带计算机(for programmer)

    打开win7的Accessories, 看到Calculator, 点击打开计算器. 可以看到32位的2进制代码:

  2. 在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  3. python处理文本文件

    在测试任务过程中都或多或少遇到自己处理文本文件的情况. 举个栗子: 客户端测试从异常日志中收集有用信息. 后端测试需要创建各种规则的压力的词表. ... 这里给大家分享一个使用python脚本处理文本 ...

  4. BI产品学习笔记

    理解现在--挖掘规律--预测未来------------------------------------------------------精准营销智能风控运营优化 多维分析挖掘预测敏捷BI 分析展示 ...

  5. 用rman恢复备库;遇到备库起不来一个案例 ORA-01152:ORA-01110

    数据从主库恢复到备库:打开备库发现出现异常 SQL> alter database open; alter database open * ERROR at line 1: ORA-10458: ...

  6. HQL的执行过程

    解释器.编译器.优化器完成HQL查询语句从词法分析.语法分析.编译.优化以及查询计划(Plan)的生成.生成的查询计划存储在HDFS中,并在随后有mapreduce调用执行. 举个例子: 第一步:输入 ...

  7. Python 入门(七)函数

    什么是函数 我们知道圆的面积计算公式为: S = πr² 当我们知道半径r的值时,就可以根据公式计算出面积.假设我们需要计算3个不同大小的圆的面积: r1 = 12.34 r2 = 9.08 r3 = ...

  8. Windows版Nginx启动失败之1113: No mapping for the Unicode character exists in the target multi-byte code page

    Windows版Nginx启动一闪,进程中未发现nginx进程,查看nginx日志,提示错误为1113: No mapping for the Unicode character exists in ...

  9. piblog企划

    今天开始准备根据廖雪峰的博客中的教程来完成一个python项目. 心想是以后用来作自己的博客的,那就取一个(自己感觉)好听的名字吧,然后就取名叫“piblog”,中文名就是“派博客”. 心想首先是给自 ...

  10. Error setting expression 'XXX' with value 设置表达式“XXX”时出错 解决方法

    1.表达式“xxx”在所调用的action里没有与之对应的对象: 2.action里有该对象作为私有成员变量但是没有get&set方法.