这个效果写了两边才搞出来,写第一遍的时候是凭着自己对这个效果的记忆去写的,重写了ScrollView,在初始化完毕给它强制添加了一个View,并设置paddingtop为-view的高度隐藏它,然后通过onTouch事件一点点的显示。

等效果出来了,看着好像和记忆中的效果有点差距,这是才打开UC又对比了一下,结果:人家是从头部开始显示,而我的是从底部开始显示,导致的结果就是:我的像是普通的滑动显示,一点档次都没有。

那好吧,重写!

要从上面开始显示,那就只能默认的时候是下面的view全覆盖上面的view(暂且称之为cardview吧),然后通过拖拽来设置下面view的margintop,达到逐渐显示cardview的效果,有了思路,那就开干!

先来看看效果吧:

既然是用FrameLayout,那我先定义一个CardView继承自FrameLayout。然后强制在最上面添加一个cardview就ok,代码:

public class CardView extends FrameLayout {

private static final float TEXT_MAX_SIZE = 50f; // 文字最带值

private ViewGroup mCardView; // 上面的cardlayout

private View mFirstChild; // 该布局下的第一个子view

private TextView mCardText; // 文字

private int mCardHeight; // cardlayout的高度

private int mStartY; // 开始拖拽的y值

private int mNowMarginTop; // 保存当前的margintop

private boolean isShown; // 记录cardlayout是否显示

public CardView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public CardView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// 获取cardLayout

mCardView = (ViewGroup) LayoutInflater.from(context).inflate(

R.layout.card_layout, null);

mCardText = (TextView) mCardView.findViewById(R.id.card_text);

// 设置默认属性

mCardText.setTextSize(0.0f);

mCardView.setAlpha(0.0f);

// 测量一下cardlayout

measureView(mCardView);

// 测量后获取高度

mCardHeight = mCardView.getMeasuredHeight();

// 添加到当前布局中

addView(mCardView, 0);

}

// 测量view

private void measureView(View view) {

ViewGroup.LayoutParams lp = view.getLayoutParams();

if(null == lp) {

lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 250);

view.setLayoutParams(lp);

}

int widthMeasureSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);

int height = lp.height;

int heightMeasureSpec;

if(height > 0) {

heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

}else {

heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

}

view.measure(widthMeasureSpec, heightMeasureSpec);

}

// 当布局加载完毕后

// 这时getChildCount()才能取出值

// 在前面getChildCount()为0

// 因此这里开始才能使用getChildAt()

@Override

protected void onFinishInflate() {

super.onFinishInflate();

if(getChildCount() <= 0) {

System.err.println("no child was found!");

return;

}

// 获取第一个布局文件中定义的第一个子view

// 为什么是1呢? 因为我们上面手工添加了一个。

mFirstChild = getChildAt(1);

}

// 滑动时,设置效果和属性

private void setCurrent(int topMargin) {

// 如果超过了cardlayout的高度

// 则最大就是cardlayout的高度

if(topMargin > mCardHeight) {

topMargin = mCardHeight;

}

// 同样,小于0了,最小就是0

if(topMargin <= 0) {

topMargin = 0;

}

// 根据现在的topmargin设置cardlayout的alpha

mCardView.setAlpha(topMargin/(float)mCardHeight);

// 根据现在的topmargin设置文本的大小

mCardText.setTextSize(topMargin/(float)mCardHeight * TEXT_MAX_SIZE);

// 获取子view的layoutparams

FrameLayout.LayoutParams lp = (LayoutParams) mFirstChild.getLayoutParams();

if(null == lp) {

lp = new FrameLayout.LayoutParams(

FrameLayout.LayoutParams.MATCH_PARENT,

FrameLayout.LayoutParams.WRAP_CONTENT);

}

// 设置margintop

lp.topMargin = topMargin;

mFirstChild.setLayoutParams(lp);

mNowMarginTop = topMargin;

invalidate(); // 刷新界面

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

mStartY = (int) event.getY(); // 当按下时,记录按下的y值

break;

case MotionEvent.ACTION_MOVE:

int nowY = (int) event.getY(); // 移动时,获取y

// 如果当前不是显示状态

if(!isShown) {

setCurrent(nowY - mStartY); // 非显示状态->显示状态:使用这个逻辑

}else {

setCurrent(mCardHeight-(mStartY - nowY)); // 显示状态->非显示状态:使用这个逻辑

}

break;

case MotionEvent.ACTION_UP:

mStartY = 0; // 抬起的时候,重新设置mStartY

// 抬起了,cardlayout只有两种状态

// 显示/不显示

// 如果现在的margin值大于cardlayout高度的二分之一,则全显示

// 否则不显示

if(mNowMarginTop >= mCardHeight / 2) {

setCurrent(mCardHeight);

isShown = true;

}else {

setCurrent(0);

isShown = false;

}

break;

}

return true;

}

}

需要说明的有两点:

1、在CardView中,我们需要获取他的第一个子View(因为要改变他的margintop值来显示动态添加的那个view)。在哪获取呢?如果在构造方法中获取或报异常,因为这时候layout还没有加载完成,那我们就在layout加载完毕后获取吧,正好有个可以重写的方法:

protected void onFinishInflate()

我们在这里要做的工作很简单就是获取他的第一个view。

2、重写onTouchEvent方法,根据滑动的距离来显示card,在ACTION_MOVE中分了两种情况:“由无到有”和“由有到无”。然后不断的调用自定义方法:setCurrent来改变效果,注释里面写的很清楚了。

这里我们在ACTION_UP通过判断当前显示的是不是已经过半,如果过半,抬起的时候就全显示出来,如果没过半,就还原默认。

总结:

1、想了想slidemenu应该用这种方式也可以实现吧。

2、刚开始接触View重写,肯定还有不完美的地方,希望在以后再看到现在的代码时,能使劲的鄙视一下自己。

android 模仿uc标签页,android模仿UC首页天气效果相关推荐

  1. android 多个标签页,Android一个标签页的实现

    最近要实现一个类似于下面的页面 想着每次都要自己重新写,太麻烦了,这里记录一下自己写的自定义的view.一开始本来准备用ConstraintLayout的,但是这货addview的时候总有bug,就用 ...

  2. android 模仿uc标签页,仿uc浏览器菜单实现【原创】

    UC浏览器的菜单我们可以发现,UC的菜单就是一个个标签页显示在了PopupWindow上,所以可以想到使用PopupWindow+TabHost来实现类似的效果.首先要重写PopupWindow pu ...

  3. android 模仿uc标签页,模仿UCweb菜单 - 白羽雕弓 - 博客园

    UCWeb的菜单看起来不错,自己想模仿做一个,苦恼一直没有思路 google了几天,终于找到一个帖子  http://www.eoeandroid.com/viewthread.php?tid=288 ...

  4. android 版edge标签页,Edge Beta 版新功能:同步标签页和历史记录(附.APK)

    软餐(ruancan.com)获悉,Android 平台上的微软 Edge Beta 版最新提供了和 PC 版 Edge 同步标签页和历史记录 的功能. 据悉,微软已经在安卓版的 Edge 浏览器 v ...

  5. android透明功能引导页,Android 利用PagerView做引导页

    先看实际效果,这个是用了一个APP里面的图片,不是自己的图. 第一步:创建引导页的 Activity,先在引导页上的xml定义一个ViewPager和用于下面放置圆点导航的ViewImage. and ...

  6. android 如何去掉自定义标签页,Android中为TextView增加自定义的HTML标签

    Android中的TextView,本身就支持部分的Html格式标签.这其中包括常用的字体大小颜色设置,文本链接等.使用起来也比较方便,只需要使用Html类转换一下即可.比如: textView.se ...

  7. android 获取手机a标签页,Android关于对Jsoup抓取a标签和br标签之间的解决办法...

    Jsoup官方给出的文档,链接:http://www.open-open.com/jsoup/ 描述问题: 学校教务处系统中,我想获取所有科目以及对应的成绩,因此我采用了Jsoup抓取 采集成绩:fe ...

  8. android 多个启动页,Android启动页的问题整理

    在一个 方法一:设置起动模式 一个Activity有四种启动模式:standard, singleTop, singleTask, singleInstance. standard: 标准模式,一调用 ...

  9. android 美团商家详情页,Android仿美团团购详情页下拉图片放大效果,简单可直接用在项目中...

    一:介绍 大家在项目中,可能需要像美团团购详情页面下拉的时候美食图片放大的效果,在这里就给大家介绍如何实现这种效果,只有很少的代码,而且控件全部是安卓源生控件. 二:运行效果图 三.然后来看看如何实现 ...

最新文章

  1. linux-命令替换-通配符-重定向-管道
  2. CCF201809(Java)
  3. 【C#-枚举】枚举的使用
  4. SpringBoot番外篇(一):使用Spring Initializer快速创建Spring Boot项目(IDEA版)
  5. 企业生产环境利用ATIES对服务器进行远程备份
  6. mooc c语言第三周作业,2017moocC语言第七周答案
  7. zoom怎么解除静音_如何召开一场Zoom视频会议
  8. 智能一代云平台(三十四):后端架构一些总结
  9. “赤膊贪凉”要不得 多喝蜜水防“秋燥”
  10. 路由器连接宽带(成功上网步骤方法)
  11. JavaScript-包装类型
  12. 小学计算机知识题,小学信息技术基础知识试题
  13. 企业应当如何编制信息安全策略
  14. 针对IE 7的hack写法
  15. 导向滤波实现代码以及使用颜色先验去雾算法
  16. 机器学习数学基础之高数篇——函数极限和导数(python版)
  17. 传说中的世界500强面试题-推理能力(1)
  18. 2 4G高频PCB天线设计
  19. Ubuntu——笔记本插入耳机没有声音的解决方案
  20. Snort IPS入侵防御系统模式

热门文章

  1. 怎么在html使用百度商桥,电脑版网站如何添加爱番番(原:百度商桥)
  2. 怎么保证读取最新数据_摄影师的数据存储有多难,怎么存储大量数据并保证安全高速防水防摔防尘?SanDisk...
  3. 函数声明和函数表达式
  4. LayoutInflater——inflate方法不同参数的区别
  5. Jsp+Ssh+Mysql+Redis实现的Java Web订餐点餐
  6. 基于JAVA+SpringBoot+Mybatis+MYSQL的宝妈购母婴用品商城
  7. 使用idea的maven插件自动打jar包
  8. mysqli_fetch_row,mysqli_fetch_array,mysqli_fetch_assoc区别
  9. JAVA-5NIO之Selector
  10. vue爬坑之路2----vue实例