移动开发

Android踩坑日记:点击变暗效果的ImageView实现原理

很多时候我们使用ImagView显示图片,无论是Gilde,Fresco等图片显示框架,比如设置中心更换头像,网格相册点击预览,选择等情况,会遇到点击变暗的交互需求。 源码分析 我们想的办法是自定义一个ImageView,当点击图片时,是不是有回调方法来同时改变图片的滤镜或者蒙版等。 特意去看了View.java的源码(ImageView继承View),想看看View被点击之后是是否有回调函数可用。 View的onTouchEvent()方法 case MotionEvent.ACTION_DOWN: mHasPerformedLongPress = false; if (performButtonActionOnTouchDown(event)) { break; } // Walk up the hierarchy to determine if we're inside a scrolling container. boolean isInScrollingContainer = isInScrollingContainer(); // For views inside a scrolling container, delay the pressed feedback for // a short period in case this is a scroll. if (isInScrollingContainer) { mPrivateFlags |= PFLAG_PREPRESSED; if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } postDelayed(mPendingCheckForTap, ViewConfiguration.

Android 绘图Shader之BitmapShader

Shader Shader在计算机图形领域叫做着色器,是一组提供给GPU的绘图指令,用于告诉GPU在绘图时应该怎么绘制并对绘制的物体进行色彩渲染。 Android中定义了几种Shader给Paint使用,在Paint绘制图像时对其设置不同的Shader,绘制出来的物体就会使用Shader提供的信息进行着色。 Shader的子类有:BitmapShader、LinearGradient、ComposeShader、RadialGradient、SweepGradient BitmapShader BitmapShader是使用一张指定的图片给Paint进行着色,在绘制的时候会根据设置的TileMode(平铺模式)和图像来形成不同的效果,其中TileMode有 如下三种: CLAMP 这种模式在绘制的时候如果绘制区域超出提供的图片的尺寸,超出区域会使用超出部分的边缘颜色进行着色 REPEAT 这种模式在绘制的时候如果绘制区域超出提供的图片的尺寸,超出区域会重新使用完整的图片进行着色 MIRROR 这种模式在绘制的时候如果绘制区域超出提供的图片的尺寸,超出区域会重新使用完整的图片进行着色,并且呈镜面反转效果 BitmapShader构造函数: /** * 唯一的一个构造函数,调用这个构造函数构造一个新的BitmapShader * * @param bitmap 用于着色的bitmap对象 * @param tileX 水平方向的平铺模式. * @param tileY 垂直方向的平铺模式. */ public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY) { BitmapShader实例 public class BitmapShaderView extends View { private Paint mPaint; private Shader mShader; /** * 用于给Paint着色的图片 */ private Bitmap mBitmap; public BitmapShaderView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initial(); } private void initial(){ mPaint = new Paint(); mPaint.

[FAQ17385]录像打开EIS后画面变的突然很暗

[DESCRIPTION] 录像打开EIS后,画面变得很暗. [SOLUTION] [MT6735/53,MT6755,MT6732/52] 1. 没开EIS, recording是动态帧率. 2. 打开EIS后, recording是固定帧率为30fps. 帧率固定以后,画面会变暗. 解决办法: /vendor/mediatek/proprietary/custom/[platform]/hal/camera/camera_custom_eis.cpp bool GetEisLinkWithDfr() { return true; // true : dynamic frame rate off when eis on; false : dynamic frame rate on when eis on } 将return ture修改为false, 打开EIS后不会固定录像的帧率. [MT6580] alps\vendor\mediatek\proprietary\platform\mt6580\hardware\mtkcam\v1\hal\adapter\mtkdefault\MtkDefaultCamParameter.cpp status_t CamAdapter::setParameters() { … cam3aParam.u4ShotMode = mpParamsMgr->getShotMode(); cam3aParam.u4CamMode = mpParamsMgr->getHalAppMode(); cam3aParam.i4RotateDegree = mpParamsMgr->getInt(MtkCameraParameters::KEY_ROTATION); ////////将下面这行//// cam3aParam.bVideoStabilization = (mpParamsMgr->getVideoStabilization(); /////////////////改成///// cam3aParam.bVideoStabilization = 0;

一个高仿微博等待动画loading——等待动画的简单实现

正文 背景 大家都知道,当我们在app开发的时候,一般少不了,比如当请求网络数据时,肯定网速不好的时候。 在这种情况下,加载的时候比较慢,所以如果此时已经进入了新的界面,那么肯定不好看。 所以一般都会有一个loading等待提示框,告诉用户正在加载中,给用户更好的体验。因此这就是我教大家实现的效果,先看一下效果图吧: 我这里使用了一个handler延迟两秒钟让它消失不见。当然项目中大家可以监听自己所需要的方法,使加载框消失。 这只是简单的两种实现方式,当然还有更好的其他效果,具体可以自己实现以下,也可以去网上搜索一下。 说主题吧,我这里只是讲一下思路,具体代码可以试着写一下,当然我在最后会给大家放源代码下载地址。 第一步,先写一个自定义dialog,代码也比较详细。就是创建一个dialog,如: public static Dialog createLoadingDialog(Context context, String msg) { LayoutInflater inflater = LayoutInflater.from(context); View v = inflater.inflate(R.layout.dialog_loading, null);// 得到加载view LinearLayout layout = (LinearLayout) v.findViewById(R.id.dialog_loading_view);// 加载布局 TextView tipTextView = (TextView) v.findViewById(R.id.tipTextView);// 提示文字 tipTextView.setText(msg);// 设置加载信息 Dialog loadingDialog = new Dialog(context, R.style.MyDialogStyle);// 创建自定义样式dialog loadingDialog.setCancelable(true); // 是否可以按“返回键”消失 loadingDialog.setCanceledOnTouchOutside(false); // 点击加载框以外的区域 loadingDialog.setContentView(layout, new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));// 设置布局 /** *将显示Dialog的方法封装在这里面 */ Window window = loadingDialog.getWindow(); WindowManager.LayoutParams lp = window.

【关于适配】PopupWindow弹出时背景不变暗 或者 PopupWindow背景一闪一闪问题处理

前言: 项目开发中遇到关于PopupWindow适配性的问题,特别是在华为手机上显示就会出现类似的情况。 下面这段PopupWindow弹出时背景变暗效果的代码在网上随处可见: private void setBackgroundAlpha(float bgAlpha){ WindowManager.LayoutParams layoutParams = MainActivity.this.getWindow().getAttributes(); layoutParams.alpha = bgAlpha; //0.0-1.0 MainActivity.this.getWindow().setAttributes(layoutParams); } 1 2 3 4 5 1 2 3 4 5 解决方法: 在相关的PopupWindow方法中加入这个方法,问题完美解决。 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);//多加这一句,问题就解决了!这句的官方文档解释是:让窗口背景后面的任何东西变暗 1 2 3 1 2 3 private void setBackgroundAlpha(float bgAlpha){ WindowManager.LayoutParams layoutParams = MainActivity.this.getWindow().getAttributes(); layoutParams.alpha = bgAlpha; //0.0-1.0 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); MainActivity.this.getWindow().setAttributes(layoutParams); } 控件:自定义popwindow 机型:mi4 闪屏事件:拖动popupwindow中的listview时会导致闪屏 闪屏原因:一般而言, GPU 的帧速率应高于刷新率,才不会卡顿或掉帧。如果屏幕刷新率比帧速率还快, 屏幕会在两帧中显示同一个画面,这种断断续续情况持续发生时,用户将会很明显地感觉到动画的卡顿或者掉帧, 然后又恢复正常,我们常称之为闪屏、跳帧、延迟。 解决方案:在当前的Activity配置中添加android:hardwareAccelerated="true" 注意事项:如果把这句代码放到application中,那么会在三星部分手机上报错 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8

Android静态注册的屏幕开启和屏幕关闭的广播捕捉不到的原因

今天进行了手机屏幕亮屏、暗屏、屏幕开锁、WIFI和移动网络状态改变、开机等广播的功能实现,其中遇到了一个问题,就是无论如何,屏幕亮屏、暗屏的广播都接收不到。这是因为我在AndroidManifest.xml采用了静态 注册的缘故。事实上,对应屏幕亮屏、暗屏的广播,必须通过代码动态注册 才可以获取到广播,这是系统做出的限制。 实例代码见第一代码原创文章http://www.diyidaima.com/article/detail/km3rgm28

Android 禁止安装没有授权的第三方应用

平时也就只会跑程序,也不知道Android安装程序是个什么原理 Android应用安装有如下四种方式 1.系统应用安装――开机时完成,没有安装界面 2.网络下载应用安装――通过market应用完成,没有安装界面 3.ADB工具安装――没有安装界面。 4.第三方应用安装――通过SD卡里的APK文件安装,有安装界面 应用安装的流程及路径 应用安装涉及到如下几个目录: system/app 系统自带的应用程序,无法删除 data/app 用户程序安装的目录,有删除权限。安装时把apk文件复制到此目录 data/data 存放应用程序的数据 data/dalvik-cache 将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一); 详细介绍第4 种 apk文件安装,会弹出一个安装界面,其实这是Android调用了另外一个叫PackageInstaller的APP来专门卸载和安装 apk。这个还真没想到 首先讲讲他的主界面 PackageInstallActivity onCreate() 主要就是解析一大堆的APK信息,来判断有没有错误 initiateInstall() 检查是否安装过,有没有相同的包名 startInstallConfirm() 这里面提取权限的信息,并展示权限列表啥的,源码看的也很是头疼。。。点击确认,又到了另外一个类去进行安装的操作了。 刚开始我的想法就简单了,自己自定义个权限,第三方应用过来了我就检查它的权限列表,没有我定义的权限就不让它走后面安装的步骤,弹出了Dialog警告。 提取权限列表的代码 private List getPermissions(PackageInfo pi){ String[] ps=pi.requestedPermissions; if(ps!=null){ for (String str:ps) { Log.e(“AAAAAAAAAAAA”,str); } return Arrays.asList(ps); } return null; } private void showFailDialog(){ final AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle(“安装提示”) .setMessage(“该第三方应用缺少权限:com.example.xiefei.permission,不允许安装”) .setCancelable(false) .setPositiveButton(“确定”, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) {

解决Android手机USB调试是灰色的问题

手上有一部HTC D820t型号的手机,并且已经开启了开发者选项(这是废话,不然也看不到USB调试),然而USB调试就是灰色的。怎么调怎么选择连接选项都不行,重置手机也不行,后来在网上搜到说需要插入手机SIM才行。 没有插入SIM卡,手机不让使用 连接方式不对,选为“文件传输”

改变Android状态栏字体为黑色

最近做的这个项目因为标题栏的颜色是一种很浅的颜色,我在开发时也没有关注标题栏字体的颜色.然后昨天UI拿 着手机突然过来找我,说我手机上的标题栏的字体怎么这么浅,我拿过来看了看,原来是她手机标题栏字体的颜色是 白色的,所以基本上看不清,我拿我自己的手机看了看,发现我手机的标题栏字体颜色却是黑色的(我手机是魅族5, 她的是vivo x9),所以我当时就怀疑是不是系统的原因.然后就上网搜了下发现:Android4.4以上系统版本可以修改 状态栏颜色,但是只有小米的MIUI、魅族的Flyme和Android6.0以上系统可以把状态栏文字和图标换成深色,其他 的系统状态栏文字都是白色的,换成浅色背景的话就看不到了.而且魅族设置状态栏图标为深色和魅族特定的文 字风格,Flyme4.0以上;小米的MIUI设置状态栏字体图标为深色,需要MIUIV6以上,最后就找到了下面这篇博客: http://www.jianshu.com/p/7f5a9969be53 他写了一个工具类,下面我就贴出来: class StatusBarUtil { /** * 修改状态栏为全透明 * @param activity */ @TargetApi(19) public static void transparencyBar(Activity activity){ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = activity.getWindow(); window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(Color.TRANSPARENT); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window =activity.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } } /** * 修改状态栏颜色,支持4.4以上版本 * @param activity * @param colorId */ public static void setStatusBarColor(Activity activity,int colorId) { if (Build.

性能优化十六之Wake_Lock唤醒锁以及JobScheduler使用

前言 上一篇博客记录了电量优化中的第一种优化,把一些不需要及时和用户交互的一些操作,放到当用户插上电源的时候。根据自己目前的知识了解,只知道三种优化方式,第二种和第三种方式接下来进行介绍。 第二种方式:网络类型选择优化 目前大部分手机都支持4G网络,殊不知蜂窝移动信号是在所有的网络类型中是最消耗电量的,很多人在使用手机的过程中,发现如果一直在使用4G移动网络,电量会持续不了多久就没电了,而相对来说WIFI会比蜂窝移动信号的电量消耗会小很多,所以我们在开发过程中可以将某些操作放在连接WIFI后进行操作。如何去判读网络类型的代码例子,网上都有。 第三种方式:wake_lock wakelock是个什么东西呢?查了很多资料了解到它是一个唤醒锁,什么是唤醒锁?它主要是相对系统的休眠而言的,意思就是我的程序给CPU加了这个锁那系统就不会休眠了,这样做的目的是为了全力配合我们程序的运行。有的情况如果不这么做就会出现一些问题,比如微信等及时通讯的心跳包会在熄屏不久后停止网络访问等问题。所以微信里面是有大量使用到了wake_lock锁(可以利用WLD进行测试)。 使用场景一:保持屏幕常亮 当Android设备空闲时,屏幕会变暗,然后关闭屏幕,最后会停止CPU的运行,这样可以防止电池电量掉的快。在休眠过程中自定义的Timer、Handler、Thread、Service等都会暂停。但有些时候我们需要改变Android系统默认的这种状态:比如玩游戏时我们需要保持屏幕常亮,比如一些下载操作不需要屏幕常亮但需要CPU一直运行直到任务完成。 1、保持屏幕常亮,最好的方式是在Activity中使用FLAG_KEEP_SCREEN_ON 的Flag。 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } 优点:这个方法的好处是不像唤醒锁(wake locks),需要一些特定的权限(permission)。并且能正确管理不同app之间的切换,不用担心无用资源的释放问题(唤醒锁如何使用下面介绍)。 注意:一般不需要人为的去掉flag,WindowManager会管理好程序进入后台回到前台的操作。如果确实需要手动清掉常亮的flag,使用 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) 2、布局文件中设置屏幕常亮: 另一个方式是在布局文件中使用android:keepScreenOn属性: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:keepScreenOn="true"> < /RelativeLayout> android:keepScreenOn = ” true “的作用和FLAG_KEEP_SCREEN_ON一样。但是使用代码的好处是你允许你在需要的地方关闭屏幕。 使用场景二:保持CPU运行 需要使用PowerManager这个系统服务的唤醒锁(wake locks)特征来保持CPU处于唤醒状态。唤醒锁允许程序控制宿主设备的电量状态。创建和持有唤醒锁对电池的续航有较大的影响,所以,除非是真的需要唤醒锁完成尽可能短的时间在后台完成的任务时才使用它。比如在Acitivity中就没必要用了。如果需要关闭屏幕,使用上述FLAG_KEEP_SCREEN_ON。 只有一种合理的使用场景,就是在使用后台服务需要在屏幕关闭情况下hold住CPU完成一些工作。这时就需要使用唤醒锁,如果不使用唤醒锁来执行后台服务,当CPU在未来的某个时刻休眠导致某个时刻任务会停止,这是我们不想看到的。 (有的人可能认为我以前写的后台服务运行得挺好的,1.可能是你的任务时间比较短;2.可能CPU被手机里面很多其他的软件一直在唤醒状态。)。下面是很多网友有同样的问题: 唤醒锁可划分为并识别四种用户唤醒锁: 标记值 CPU 屏幕 键盘 PARTIAL_WAKE_LOCK 开启 关闭 关闭 SCREEN_DIM_WAKE_LOCK 开启 变暗 关闭 SCREEN_BRIGHT_WAKE_LOCK 开启 变亮 关闭 FULL_WAKE_LOCK 开启 变亮 变亮 请注意,自 API 等级 17 开始,FULL_WAKE_LOCK 将被弃用,应用应使用FLAG_KEEP_SCREEN_ON 使用方法一: 第一步就是添加唤醒锁权限: