Android仿今日头条手界面

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);
时间: 2024-10-11 16:45:55

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

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

前言 上篇博客我们说到了今日头条频道管理的操作交互体验,我也介绍了2个GridView之间Item的相互移动.详情请參考:Android 仿今日头条频道管理(上)(GridView之间Item的移动和拖拽) 今天把相对照较复杂的gridView的拖拽也记录下.在開始之前我们事先要了解下Android的事件分发机制.网上这方面的资料也比較多.由于自己定义控件大部分要用到事件分发机制的知识. 实现思路 要实现Item的拖拽.事实上并非真正要去拖拽GridView的Item.而是使用WindowMan

仿今日头条的graidview拖动

下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里面有,可以下载看看) 三.开发思路 1.  获取数据库中频道的列表,如果为空,赋予默认列表,并存入数据库,之后通过对应的适配器赋给对应的GridView 2.  2个GridView--(1.DragGrid   2. OtherGridView) DragGrid 用于显示我的频道,带有长按拖拽效果 OtherGridView用于显示更多频道,不带推拽效果 注:由于屏幕大小不一定,外层使用ScrollView,所以

仿今日头条和qq侧滑和智慧北京的小项目 3

仿今日头条和QQ侧滑和智慧北京的小项目3 本项目图片素材均来自今日头条,QQ侧滑没有使用Android原生的NavigationDrawer,而使用的是第三方SlidingMenu,原因是这个控件暂时没有仔细研究(后期会研究并写demo),项目整体可以说是使用了一个Activity加多个Fragment,全部采用沉寂式. 前文摘要:仿今日头条和QQ侧滑和智慧北京的小项目2 TabPager(NewsPager新闻页面对应的11个子页面) 此页面相对比较复杂,所以单独用一篇blog来说明都处理了哪

[转]灯灯小程序开发手记:仿今日头条(上)

本文转自:http://www.jianshu.com/p/a1e0b8abb12d 写在前面 新的一年,祝大家新年快乐!当然对于程序员来说,新的一年,也要有新的改变.因此灯灯决定凑热闹编写微信小程序啦! 上一篇文章<记一次小程序开发过程>中,灯灯大致写了下自己第一次开发小程序的感受和流程.这一次灯灯会详细记录下自己制作一个小程序的思路.遇到的问题.涉及到的代码等和大家分享.    视频教程地址:http://study.163.com/course/introduction.htm?cour

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

vue-toutiao 这是用 vue.js 2.0 高仿 今日头条 的移动端项目,结合了原生app的部分功能以及网页版. 前言 本人是 今日头条 的重度用户,在学习vue.js过程中,在GitHub上看到了很多高仿webapp的好项目.由此在有了一定的技术积累后,开始构思使用Vue写今日头条,一是自己对于头条的喜爱,另外也是对于自己学习成果的检验. 技术栈 vue.js 2.0全家桶(vue.vuex.vue-router) axios.jsonp element-ui.iview vue-l

基于Vue 2.0高仿 &lt;今日头条&gt; 单页应用。

这是用 vue.js 2.0 高仿 今日头条 的移动端项目,结合了原生app的部分功能以及网页版. 技术栈 vue.js 2.0全家桶(vue.vuex.vue-router) axios.jsonp element-ui.iview vue-lazyload.animate.css.moment.flexible.js 在线地址 线上地址(预览地址) GitHub源码地址 说明 项目内定死 账号: admin, 密码: admin. 因为数据原因,首页请求的数据接口来自网页版今日头条,修改了一

iOS仿今日头条滑动导航

之前写了篇博客网易首页导航封装类.网易首页导航封装类优化,今天在前两个的基础上仿下今日头条. 1.网易首页导航封装类中主要解决了上面导航的ScrollView和下面的页面的ScrollView联动的问题,以及上面导航栏的便宜量. 2.网易首页导航封装类优化中主要解决iOS7以上滑动返回功能中UIScreenEdgePanGestureRecognizer与ScrollView的滑动的手势冲突问题. 今天仿今日头条滑动导航和网易首页导航封装类优化相似,这个也是解决手势冲突,UIPanGesture

iOS新闻应用源码,高仿今日头条源码等

iOS精选源码 城市列表选择 一款非常时尚的照片选择插件 优酷播放按钮动画 BRPickerView是iOS的选择器组件,主要包括:日期选择器.时... 选择位置坐下动画Demo BAButton 图片.文字.倒计时等 git 功能最全的 button 分类 企业级完整iOS项目-<新闻来了> 较为美观的多级展开列表 高仿今日头条6.2.6 Swift 简单画板的swift实现 iOS优质博客 创建一个私有的 Pods 详解 前言骚年,你听说过组件化吗?没有?但你一定玩过乐高玩具,乐高玩具本身

项目记录,仿今日头条app

项目记录,仿今日头条app,五六月份主要做的项目,第一版已经完成上架,二次开发正在进行中