2017-06-15 12:25:37 qq_15895655 阅读数 392

这里写图片描述

文章说明
本文修改自开发者源码
微信公共号:China-dvlp

如果你有想学习的文章直接关注公众号(开发者源码)回复,我会整理征稿。如果你有好的文章想和大家分享欢迎投稿,直接向我回复文章链接即可。

*
概 述

在android 中,5.0以前,我们可以利用 google 提供的api来完成转场动画,使界面的跳

转顺滑。5.0,Android提供了一种叫做:共享元素。实现,转场时界面如丝般顺滑的过

渡,为5.0新特性

1
简 单 应 用 效 果 图

这里写图片描述

2
源码下载

源码地址
http://download.csdn.net/detail/qq_15895655/9870784
100%亲测,完美运行~

平台特色:每日咨询,专属老司机开车,猿里来污里去。

这么多优质源码,想必大家早已看的眼花缭乱。
欢迎长按下图->识别图中二维码或者扫一扫关注我的公众号:

扫码,get优质源码

这里写图片描述

结束语:文章出自平台:开发者源码

2019-01-28 20:31:42 Coo123_ 阅读数 377

2018年已过,已经迎来了全新的2019,面试Android开发岗的伙伴也分享了很多自己的面试经验,这里给大家整理了网友分享的2018年秋招腾讯、饿了么、百度Android岗一面被问到的面试题,我们一起来看看:
在这里插入图片描述

腾讯Android岗一面

  1. 看到实习项目里面有写了AI摄像头,问了图像相关的东西(噩梦的开始。。问我图片有几通道,占多少内存,打扰了,最后让我猜猜看。。。)
  2. ***作系统相关(32位系统为啥只能装4GB内存,ARM和X86区别)?
  3. Java中的各种锁优劣势,哪种锁消耗最低?
  4. TCP相关,如何优化?
  5. 说说ContentProvider、ContentResolver、ContentObserver 之间的关系?
  6. LinearLayout、RelativeLayout、FrameLayout的特性及对比,并介绍使用场景?
  7. 在manifest 和代码中如何注册和使用BroadcastReceiver?
  8. Android中哪种布局性能最高?
  9. 手写算法:不使用快慢指针找出入环节点?
  10. HashSet的实现原理?
  11. 未来准备在哪个方向学习?
  12. 你还有什么问我的?

饿了么Android岗一面

(显示是从杭州阿里打来的电话,上礼拜一面至今没消息,估计凉凉)

  1. 双亲委托机制?
  2. 插件化原理?
  3. 垃圾回收机制及其优缺点?
  4. PathClassLoader和DexClassLoader区别?
  5. 说下Binder?
  6. Android旋转屏幕后Activity生命周期,Bundle是存储在哪儿的?
  7. 事件分发机制?
  8. Handler实现?
  9. Java内存?
  10. OkHttp设计模式?
  11. 算法。

百度Android岗一面

  1. 算法:寻找出现超过一半的数字?
  2. HashMap原理?
  3. 热更新原理?
  4. AstncTask+HttpClient 与 AsyncHttpClient有什么区别?
  5. Https握手过程?
  6. RecycleView原理?
  7. RecycleView的使用?
  8. Hybrid通信原理是什么,有做研究吗?
  9. ListView图片加载错乱的原理和解决方案?
  10. 对称加密与非对称加密?
  11. TCP、UDP差别?
  12. TCP保证可靠的手段?

想要获取面试题和面试题答案请加加:936332305 / 链接:点击链接加入【安卓开发架构】:https://jq.qq.com/?_wv=1027&k=515xp64

在这里插入图片描述

2017-05-16 14:13:16 hzl4683451 阅读数 441

最近业务需求做个类似饿了么首页搜索框效果,在网上搜了一下也有其他博客做过,效果挺像的,但是展示效果不太好,会导致搜索框内容变形。

后来自己就模仿了一下,自己写了实一下,现起来也很简单,主要是使用到ValueAnimator,先看效果。


package com.lel.search;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.lel.search.databinding.ActivitySearchBinding;

public class SearchActivity extends AppCompatActivity {

    ActivitySearchBinding mBinding;
    private int mWidth,mCurrWidth,mHeight,mCurrHeight;
    private int mLeftMargin,mCurrLeftMargin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWidth = getIntent().getIntExtra("width",0);
        mHeight = getIntent().getIntExtra("height",0);
        mLeftMargin = getIntent().getIntExtra("leftMargin",0);
        mBinding = DataBindingUtil.setContentView(this,R.layout.activity_search);
        inputAnimator(mBinding);
        mBinding.btnNavBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                outputAnimator(mBinding);
            }
        });
    }



    /**
     * 进场动画
     * @param viewBinding
     */
    public void inputAnimator(final ActivitySearchBinding viewBinding){
        viewBinding.rvList.getBackground().setAlpha(0);
        final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewBinding.searchContainer.getLayoutParams();
        final LinearLayout.LayoutParams lp2 = (LinearLayout.LayoutParams) viewBinding.layoutSearch.getLayoutParams();
        final LinearLayout.LayoutParams lp3 = (LinearLayout.LayoutParams) viewBinding.superContainer.getLayoutParams();
        ValueAnimator valueAnimator = ValueAnimator.ofFloat( 0f,1.0f);
        valueAnimator.setDuration(250);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 0.0~1.0
                float value= (float) animation.getAnimatedValue();
                viewBinding.btnNavBack.setAlpha(value);
                viewBinding.tvSearch.setAlpha(value);
                viewBinding.rvList.getBackground().setAlpha((int) (255 * value));
                // 搜索框宽度从100%到75%
                lp.width = (int)(mWidth - (mWidth * 0.25 * value));
                mCurrWidth = lp.width;
                viewBinding.searchContainer.setLayoutParams(lp);
                // 搜索框父控件高度从100dp到56dp
                lp3.height = (int)(mHeight - ((mHeight - dip2Px(56)) * value));
                mCurrHeight = lp3.height;
                viewBinding.superContainer.setLayoutParams(lp3);
                // 搜索框中间内容向左偏移
                mCurrLeftMargin = (int) (mLeftMargin * value);
                lp2.setMargins(- mCurrLeftMargin,0,0,0);
                viewBinding.layoutSearch.setLayoutParams(lp2);
            }
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                KeyboardUtils.openKeyboard(viewBinding.etSearch,SearchActivity.this);
            }
        });
        valueAnimator.start();
    }


    /**
     * 退场动画
     * @param viewBinding
     */
    public void outputAnimator(final ActivitySearchBinding viewBinding){
        final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewBinding.searchContainer.getLayoutParams();
        final LinearLayout.LayoutParams lp2 = (LinearLayout.LayoutParams) viewBinding.layoutSearch.getLayoutParams();
        final LinearLayout.LayoutParams lp3 = (LinearLayout.LayoutParams) viewBinding.superContainer.getLayoutParams();
        ValueAnimator valueAnimator = ValueAnimator.ofFloat( 1.0f,0.0f);
        valueAnimator.setDuration(250);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value= (float) animation.getAnimatedValue();
                viewBinding.btnNavBack.setAlpha(value);
                viewBinding.tvSearch.setAlpha(value);
                viewBinding.rvList.getBackground().setAlpha((int) (255 * value));
                lp.width = (int)(mCurrWidth + (mWidth * 0.25 * (1- value)));
                viewBinding.searchContainer.setLayoutParams(lp);
                lp3.height = (int)(mCurrHeight + ((mHeight - mCurrHeight) * (1- value)));
                viewBinding.superContainer.setLayoutParams(lp3);
                lp2.setMargins((int) (-mCurrLeftMargin + mLeftMargin * (1- value)),0,0,0);
                viewBinding.layoutSearch.setLayoutParams(lp2);
            }
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                KeyboardUtils.closeKeyboard(viewBinding.etSearch,SearchActivity.this);
                finish();
                // 发现在某些手机系统自带的退场动画无法取消,强制使用自定义的退场动画 (其实动画什么也没做)
                overridePendingTransition(R.anim.enter, R.anim.exit);
            }
        });
        valueAnimator.start();
    }

    /** Dip换Px */
    public int dip2Px(int dip) {
        float density = getResources().getDisplayMetrics().density;
        int px = (int)(dip * density + .5f);
        return px;
    }

}


本项目Github地址:https://github.com/huangzhangliang/EleSearchLayout


推荐一下另一个项目,MvvM结合Presenter快速开发架框:

https://github.com/huangzhangliang/MvvMBaseProject


2017-01-03 17:12:33 anye_bbk 阅读数 2473

1。饿了么的首页进入搜索的动画效果相信很多人都见过,今天跟大家分享一下实现效果,废话不多说,先上图

要说实现原理,其实很简单,虽然看起来是一个Activity,其实是两个,首页Activity负责跳转至搜索页的Activity,而搜索页Activity负责整个动画的渐变过程,搜索页的Activity其实拥有首页Activity的相同的导航栏,当点击进入搜索页的时候,传入当前Edittext的坐标,

tvSearchRlt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,SearchActivity.class);
                int location[] = new int[2];
                tvSearchRlt.getLocationOnScreen(location);
                intent.putExtra("x",location[0]);
                intent.putExtra("y",location[1]);
                startActivity(intent);
                overridePendingTransition(0,0);
            }
        });

然后把搜索页的搜索框的位置移动到首页搜索框对应的位置

 float originY = getIntent().getIntExtra("y", 0);

        int location[] = new int[2];
        mSearchBGRlt.getLocationOnScreen(location);

        final float translateY = originY - (float) location[1];

        frameBgHeight = frameBg.getHeight();

        //放到前一个页面的位置
        mSearchBGRlt.setY(mSearchBGRlt.getY() + translateY);

当然了 不光是搜索框的位置,其他控件的位置也需要移动到相应的位置,这样才能实现整体向上平移

mHintTxt.setY(mSearchBGRlt.getY() + (mSearchBGRlt.getHeight() - mHintTxt.getHeight()) / 2);
        mbackIv.setY(mSearchBGRlt.getY() + (mSearchBGRlt.getHeight() - mbackIv.getHeight()) / 2);
        mSearchTxt.setY(mSearchBGRlt.getY() + (mSearchBGRlt.getHeight() - mSearchTxt.getHeight()) / 2);

对于组件移动位置的操作其实在我的代码里面是可以不用的,原因之前说了,搜索页的导航栏几乎和首页的导航栏的布局是一样的,也就是原本他们的位置就重叠,这里添上是防止两者的组件位置不一致的情况。

好了,接下来就是重点了,通过valueAnimator实现渐变的效果

   final ValueAnimator translateVa = ValueAnimator.ofFloat(mSearchBGRlt.getY(), mSearchBGRlt.getY() - 100);
        translateVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mSearchBGRlt.setY((Float) valueAnimator.getAnimatedValue());
                ViewGroup.LayoutParams linearParams = frameBg.getLayoutParams(); //取控件textView当前的布局参数
                linearParams.height = (int) (frameBgHeight-(searchBgHeight-(Float) valueAnimator.getAnimatedValue())*2); 
                frameBg.setLayoutParams(linearParams);
                mbackIv.setY(mSearchBGRlt.getY() + (mSearchBGRlt.getHeight() - mbackIv.getHeight()) / 2);
                mHintTxt.setY(mSearchBGRlt.getY() + (mSearchBGRlt.getHeight() - mHintTxt.getHeight()) / 2);
                mSearchTxt.setY(mSearchBGRlt.getY() + (mSearchBGRlt.getHeight() - mSearchTxt.getHeight()) / 2);
            }
        });
这里就是组件高度动态改变的代码

 ViewGroup.LayoutParams linearParams = frameBg.getLayoutParams(); //取控件textView当前的布局参数
                linearParams.height = (int) (frameBgHeight-(searchBgHeight-(Float) valueAnimator.getAnimatedValue())*2); 
                frameBg.setLayoutParams(linearParams);
这句的目的就是实现导航栏高度的变化

光有这一个动画肯定是不够的

        ValueAnimator scaleVa = ValueAnimator.ofFloat(1, 0.8f);
        scaleVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mSearchBGRlt.setScaleX((Float) valueAnimator.getAnimatedValue());
            }
        });

        ValueAnimator alphaVa = ValueAnimator.ofFloat(0, 1f);
        alphaVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mContentFrame.setAlpha((Float) valueAnimator.getAnimatedValue());
                mSearchTxt.setAlpha((Float) valueAnimator.getAnimatedValue());
                mbackIv.setAlpha((Float) valueAnimator.getAnimatedValue());
            }
        });
        ValueAnimator alphaVa2 = ValueAnimator.ofFloat(1f, 0);
        alphaVa2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                locationTv.setAlpha((Float) valueAnimator.getAnimatedValue());
                recommandTv.setAlpha((Float) valueAnimator.getAnimatedValue());
            }
        });

这样才显得多姿多彩,

最后给以上动画设置持续时长并启动动画

        alphaVa.setDuration(500);
        alphaVa2.setDuration(300);
        translateVa.setDuration(500);
        scaleVa.setDuration(500);

        alphaVa.start();
        alphaVa2.start();
        translateVa.start();
        scaleVa.start();
这样就完成了整个动画的渐变过程。而退出的时候执行反向操作,具体请看代码
github项目源码




2019-01-08 15:25:38 ld11620967 阅读数 181

Android精选源码

Android通用圆角布局源码

Android天气应用源码,界面美观

image

一个支持定制的树状 Android 自定义View

image

PIN 码专用输入控件,支持任意长度和输入任意数据

image

Android实现日食加载动画效果

image

kotlin实现的Android Spannable API

image

Android实现美团、饿了么首页分页导航菜单功能源码

image

Android一个方便可来处理可逆动画的效果

Android优质博客

跟上脚步,进入后台执行新时代

随着近几年来 Android 的不断发展,Google 逐步加强了对于后台执行的优化和限制。为了开发出现代化的 Android 应用,开发者需要学习如何通过最新方式来管理后台任务。系统如何判定应用处于后台?在理解后台执行这个概念之前,我们先来看看 Android 系统是如何定义前台应用的。当应用满足以下任意条件时,系统… 阅读原文

Android工程内嵌Flutter,跨平台的渐进式解决方案

其实2017年的时候就已经接触Flutter了,但也只是写了个HelloWorld,一方面是Flutter在那时候还只是preview版本,另一方面ReactNative在那时候非常火热,忙于用ReactNative重构项目,错过了入坑Flutter的第一梯队。在谷歌的2018IO大会上Flutter再一次成为了跨平台… 阅读原文

IT干货:Android开发学习路线与总结

第一阶段:Java面向对象编程1.Java基本数据类型与表达式,分支循环。2.String和StringBuffer的使用、正则表达式。3.面向对象的抽象,封装,继承,多态,类与对象,对象初始化和回收;构造函数、this关键字、方法和方法的参数传递过程、static关键字、内部类,Java的垃圾回收机制,Javadoc… 阅读原文

如何获得更小的应用文件尺寸?来了解下 Android App Bundle

对于手机用户来说,“存储空间不足” 警告有时会显得非常烦人。时至今日,手机存储容量仍然是有限的。虽然存储容量多年来一直在增长,但是填充在我们手机里的东西:音乐、应用、游戏、照片等也同样在增长。如何针对不同的用户给出最优的安装体验,正是 Android App Bundle 所要解决的问题。本文将阐述 App… 阅读原文

Android快速实现美团、饿了么首页分页导航菜单功能

前段时间公司移动端App新增一个模块,类似美团团购的功能,首页有个类似美团的分页菜单的功能,用过美团和饿了么的app的童鞋应该清楚这一功能。首页菜单可以分页切换,类似我们的banner广告切换效果,只不过只能手动切换。所以整个分页效果,我们可以采用Viewpager实现,里面的菜单项我们则可以采用RecyclerVie… 阅读原文

欢迎扫码关注微信公众号

没有更多推荐了,返回首页