Android 仿腾讯应用宝 之 Toolbar +Scroolview +tab滑动悬停效果

先说下最近做应用市场,想要的效果如下:

1、上面actionbar使用的toolbar最新的工具条来代替acionbar.

2、toolbar下面有一个 app详情

3、app详情下面有一个滑动tab ,tab下是viewpage ,viewpage里面嵌套的是2个Fragment,一个是Scrollview,一个是ListView。

要实现,监听Scrollview或者ListView滚动事件,来推挤tab向上移动,并且悬停在Toolbar下面。

http://download.csdn.net/detail/xufeifandj/8431071

具体效果如图:




代码不多解释,直接下载demo自行运行demo哈。稍后放源码。

声明:本代码基于其他开源项目,修改而来。

package com.github.ksoichiro.android.observablescrollview.samples;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.example.toolbar.R;
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
import com.github.ksoichiro.android.observablescrollview.ScrollState;
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.ViewPropertyAnimator;
public class ViewPagerTabScrollViewActivity extends ActionBarActivity implements ObservableScrollViewCallbacks {

    private View mHeaderView;
    private View appinfo;
    private int mBaseTranslationY;
    private ViewPager mPager;
    private NavigationAdapter mPagerAdapter;
    private Toolbar toolbar;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_viewpagertab);
        toolbar=(Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mHeaderView = findViewById(R.id.header);
        ViewCompat.setElevation(mHeaderView, getResources().getDimension(R.dimen.toolbar_elevation));
        appinfo = findViewById(R.id.apptitleview);
        mPagerAdapter = new NavigationAdapter(getSupportFragmentManager());
        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mPagerAdapter);

        SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
        slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
        slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent));
        slidingTabLayout.setDistributeEvenly(true);
        slidingTabLayout.setViewPager(mPager);

        // When the page is selected, other fragments' scrollY should be adjusted
        // according to the toolbar status(shown/hidden)
        slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i2) {
            }

            @Override
            public void onPageSelected(int i) {
                propagateToolbarState(toolbarIsShown());
            }

            @Override
            public void onPageScrollStateChanged(int i) {
            }
        });

        propagateToolbarState(toolbarIsShown());
    }

    @Override
    public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
    	//判断如果是拖动
        if (dragging) {
            int toolbarHeight = appinfo.getHeight();
            float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView);
            if (firstScroll) {
                if (-toolbarHeight < currentHeaderTranslationY) {
                    mBaseTranslationY = scrollY;
                }
            }
            float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
            ViewPropertyAnimator.animate(mHeaderView).cancel();
            ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
        }else{
        	if(!firstScroll){
        		int toolbarHeight = appinfo.getHeight();
        		float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
                ViewPropertyAnimator.animate(mHeaderView).cancel();
                ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
        	}
        	
        }
    }

    @Override
    public void onDownMotionEvent() {
    }

    @Override
    public void onUpOrCancelMotionEvent(ScrollState scrollState) {
        mBaseTranslationY = 0;

        Fragment fragment = getCurrentFragment();
        if (fragment == null) {
            return;
        }
        View view = fragment.getView();
        if (view == null) {
            return;
        }

        int toolbarHeight = appinfo.getHeight();
        final ObservableScrollView scrollView = (ObservableScrollView) view.findViewById(R.id.scroll);
        if (scrollView == null) {
            return;
        }
        int scrollY = scrollView.getCurrentScrollY();
        if (scrollState == ScrollState.DOWN) {//按下
        	//判断滑动到顶部的时候,开始显示 toolbar 不是顶部的  隐藏toolbar
        	
        	if(scrollView.getScrollY()<=toolbarHeight){
        		showToolbar();
        	}else{
                hideToolbar();
        	}
        	

        } else if (scrollState == ScrollState.UP) {//抬起
            if (toolbarHeight <= scrollY) {
                hideToolbar();
            } else {
                showToolbar();
            }
        } else {
        	//
            // Even if onScrollChanged occurs without scrollY changing, toolbar should be adjusted
            if (toolbarIsShown() || toolbarIsHidden()) {
                // Toolbar is completely moved, so just keep its state
                // and propagate it to other pages
                propagateToolbarState(toolbarIsShown());
            } else {
                // Toolbar is moving but doesn't know which to move:
                // you can change this to hideToolbar()
                showToolbar();
            }
        }
    }

    private Fragment getCurrentFragment() {
        return mPagerAdapter.getItemAt(mPager.getCurrentItem());
    }

    private void propagateToolbarState(boolean isShown) {
        int toolbarHeight = appinfo.getHeight();
        //设置scrollY尚未创建的片段
        // Set scrollY for the fragments that are not created yet
        mPagerAdapter.setScrollY(isShown ? 0 : toolbarHeight);
        //设置活动scrollY碎片

        // Set scrollY for the active fragments
        for (int i = 0; i < mPagerAdapter.getCount(); i++) {
            // Skip current item
            if (i == mPager.getCurrentItem()) {
                continue;
            }

            // Skip destroyed or not created item
            Fragment f = mPagerAdapter.getItemAt(i);
            if (f == null) {
                continue;
            }

            ObservableScrollView scrollView = (ObservableScrollView) f.getView().findViewById(R.id.scroll);
            if (isShown) {
                // Scroll up
                if (0 < scrollView.getCurrentScrollY()) {//滚动到 顶部
                    scrollView.scrollTo(0, 0);
                }
            } else {
                // Scroll down (to hide padding)//滚动到底部
                if (scrollView.getCurrentScrollY() < toolbarHeight) {
                    scrollView.scrollTo(0, toolbarHeight);
                }
            }
        }
    }

    private boolean toolbarIsShown() {
        return ViewHelper.getTranslationY(mHeaderView) == 0;
    }
    private boolean toolbarIsHidden() {
        return ViewHelper.getTranslationY(mHeaderView) == -appinfo.getHeight();
    }

    private void showToolbar() {
        float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
        if (headerTranslationY != 0) {
            ViewPropertyAnimator.animate(mHeaderView).cancel();
            ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start();
        }
        propagateToolbarState(true);
    }

    private void hideToolbar() {
        float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
        int toolbarHeight = appinfo.getHeight();
        if (headerTranslationY != -toolbarHeight) {
            ViewPropertyAnimator.animate(mHeaderView).cancel();
            ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start();
        }
        propagateToolbarState(false);
    }

    private static class NavigationAdapter extends CacheFragmentStatePagerAdapter {

        private static final String[] TITLES = new String[]{"Applepie", "Butter Cookie"};

        private int mScrollY;

        public NavigationAdapter(FragmentManager fm) {
            super(fm);
        }

        public void setScrollY(int scrollY) {
            mScrollY = scrollY;
        }

        @Override
        protected Fragment createItem(int position) {
            Fragment f = new ViewPagerTabScrollViewFragment();
            if (0 <= mScrollY) {
                Bundle args = new Bundle();
                args.putInt(ViewPagerTabScrollViewFragment.ARG_SCROLL_Y, mScrollY);
                f.setArguments(args);
            }
            return f;
        }

        @Override
        public int getCount() {
            return TITLES.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return TITLES[position];
        }
    }
}

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

jni.h 文件 - 2015-02-21 10:02:01

/*  * Copyright (C) 2006 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://
1.介绍DatePicker和TimePicker两种实现动态输入日期和时间的功能 2.介绍DataPickerDialog和TimePickerDialog两种实现动态输入日期和时间的对话框 3,介绍两组针对监测日期时间改变的监听器包含:               OnDataChangedListener和OnTimeChangedListener()               OnDataSetListener和OnTimeSetListener()      当用户更改了DataPicker里
1、首先下载Texturepackage工具,网上有破解版的,也可以到官网下载使用免费版,https://www.codeandweb.com/texturepacker/,接着就是简单的安装不在过多的介绍。 2、打开我们的Texturepackage工具,准备好我们的图片,本人使用的资源图片来自网上,如图: ,接着就是全选拖拽到Texturepackage工具的右端,Texturepackage就会自动帮你填充好,剩下的就是对图片进行设置,如图: 3、接下来就是把Texturepackage生成的Png
1、监控输出日志接口 /**  *   * 监控输出日志接口  */ public interface LogcatObserver { /** *  * @param info *            输出的日志信息 */ public void handleLog(String info); } 2、继承一个服务 public class LogcatScannerService extends Service implements LogcatObserver { private String i

Android - 延迟执行PostDelayed - 2015-02-21 10:02:01

延迟执行PostDelayed 本文地址:http://blog.csdn.net/caroline_wendy Android程序中,使用 postDelayed()方法 ,表示,在一段时间之后,执行新的线程,即可以达到一段特定程序延迟执行的目的。 使用: // 延迟15秒 new Handler().postDelayed(new Runnable() { public void run() { // do something } }, 15 * 1000); 注意: 引用的 路径 是: import
通知有几种,吐司Toast是其中一种。以下介绍系统默认的通知,这个有时不能满足项目需求,需要自定义的Toast RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" andro
        前两天有个刚学习使用cocos2d-js的同事问我,怎么实现一个功能:点击一个按钮UI显示 计 数加1,按住不放UI计数就不停的加。 这个功能不就是个长按事件吗?我给他描述了下实现长按事件的思路: 1. 在控件touchBegan时,使用 一次性定时器scheduleOnce传入touchLong函数,设定1秒后执行。 2.  touchLong触发时,开启schedule传入addOnce函数(ui显示计数加1),设定每0.1秒执行一次。 3.  在touchEnded时执行unsche
1.excel转json   这个可以参见前辈python的方式: https://github.com/gdgoldlion/ExcelAndJSON   不过这个需要装python和xlrd,装xlrd的时候需要用命令: python setup.py install   在win32上用批处理这样转换excel到json: python %~dp0../src/excel_and_json.py singlebook -o ./ -i test.xlsx 2.js里读取json fs.readFil
iOS 8 SDK向开发者公开了Touch ID指纹识别功能,允许App对用户身份进行本地验证。使用Touch ID非常简单,只需要2步即可: 1. 检查Touch ID是否可用。 2. 获得指纹验证结果。 下面以一个简单的例子来说明如何使用Touch ID。 创建一个新的项目,向界面设计器中添加一个按钮。使用Touch ID需要引入LocalAuthentication框架: import LocalAuthentication 在按钮的Touch Up Inside事件中我们首先检查Touch ID功
sizeWithFont在ios7.0之后失效 cell. myCourse . text =cell_info. course ; cell. myCourse . font = FONT ; CGSize myCourseSize=[cell. myCourse . text sizeWithAttributes :[ NSDictionary dictionaryWithObjectsAndKeys :cell. myCourse . font , NSFontAttributeName , nil