Android

RecyclerView 点击事件处理

RecyclerView不像ListView那样,提供了setOnItemClickListener,所以一般情况需要我们自己定义一个接口实现这个功能。我一般会通过Adapter去暴露出来一个接口,便于上层获取位置和点击事件。 首先在Adapter中新建一个接口 public static interface OnItemClickListener { void onItemClicked(View v, int postion); } 创建一个对应的实例,并且提供set/get方法 private OnItemClickListener onItemClickListener; public OnItemClickListener getOnItemClickListener() { return onItemClickListener; } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.

  • Domon
    Domon
1 min read
Android

GoogleCast集成简介

最近由于需要维护这一方面的东西,随即看了一下网络文档。发现中文圈还比较少。这篇就作为我的记录。详细的信息建议在在Google Cast官方文档里面查看,非常的全。Google Cast之前叫做Google Chromecast,可以把它理解成为一个SDK。硬件可以实现这样的SDK,例如国外的一些盒子,FireTV,PCCW的盒子以及谷歌自己的Chromecast硬件设备。**它的作用就是能将手机,Pad,浏览器的内容投射到连接有Chromecast设备的屏幕上。**挺方便的,在家看个YouTube或者在工作场所需要投屏展示内容的时候,都非常的便利。 Google Cast 分为两端:sender和receiver。就拿U2B举例子,在Android手机安装的软件叫做sender,在盒子里相应接收响应请求的叫做receiver。一般来Google自家的程序会有一个默认的由谷歌开发的receiver,当然还可以通过API自定义一个可以处理定制化的sender消息的receiver,例如TED的receiver。 Receiver的结构挺有意思,其实就是一个能运行Chrome的硬件设备,

  • Domon
    Domon
4 min read
Android

Android show/hide softKeyboard

最近项目中需要有一个地方隐藏键盘和显示键盘。其实是一个比较简单的问题,但是由于我们项目架构的原因。一个Activity中内嵌了很多个Fragment,通过事件去驱动不同的Fragment展现出来。举个例子,注册流程实际上是一个Activity,然后其中包含了ResetPasswordFragment,forgetPasswordFramgent,loginFragment等等。如果用户在Login界面的EditView输入账号密码的时候,通过back键恢复到了上一个Activity的时候,键盘是无法隐藏掉的。 为了解决这个问题,我的第一次解决的方案是这样。通过在VM层中添加一个变量hideSoftKeyboard,然后给XML设定一个自定义的BindingAdapter,传入这个变量。 @BindingAdapter("showSoftKeyboard") public static void showSoftKeyboard(View view, Boolean showSoftKeyboard) { if (!showSoftKeyboard) { InputMethodManager

  • Domon
    Domon
2 min read
Android

RxJava ignoreElement改造成Completable

这两天被一个RxJava的操作符给坑了,就是ignoreElement()。我们在Post一个请求的时候,例如上传用户信息到API当中。 public Observable<Void> delete(String profileId) { return accountApi.deleteProfileById(profileId, null) .ignoreElements(); } 如果这样写的话,会导致上在调用这个delete接口的时候,无法执行**onNext()**里面的逻辑,为什么会这个样子,具体文档里面给的图 很简单明了就可以知道。可以看看ignoreElements这个Operator怎么实现的: public static <T> OperatorIgnoreElements&

  • Domon
    Domon
2 min read
Android

EidtText点击事件第一次不生效

这两天在开发一个功能的时候,发现项目的UX要求EditText点击出来一个AlterDialog。在一顿setOnClickListener操作之后,我发现了一个小问题。在点击的时候,需要点第二次才会show出来这个Dialog。原因是EditText这个控件需要在第一次点击的时候获取焦点,第二次点击才触发OnClick事件。非常合理,因为EditText的作用是为了输入文字,所以需要先获取焦点。 查了下资料,发现改为onTouchListener就可以解决问题,只不过这里需要注意下OnTouch会调用两次,在手指按下和释放的时候。因此,需要添加一个flag来消除这个操作。 view.setOnTouchListener(new View.OnTouchListener() { int touch_flag = 0; @Override public boolean onTouch(View view, MotionEvent

  • Domon
    Domon
3 min read
Android

Fragment二次进入刷新

对于Activity来说我们想要去做用户Back后的逻辑很容易,直接从生命周期的**onRestart()**中做处理就好,例如用户从ActB返回到AtcA中,我们想要把统计分析数据上传一份到第三方统计平台中。但是对于Fragment来说,它的生命周期其实是依附于外层的Activity的,这样对于上面这个简单的需求就需要换一个思路处理。 假设我们现在有1个Activity和2个Fragment,当用户从ActivityA->FragmentA->FragmentB时,这时,我如果想获得这三个View的打开的状态的话,想一想我们可以怎么做。Activity简单,放在**onCreate()**里面就可以。返回的话就需要对于中间这个FragmentA做一下判断,确保它的第二次打开不会上传上去。因此,我们可以设置一个变量来记录当前Fragment初始化与否。 private boolean isFirstLoading = true; /** * 在Fragment可见的时候刷新数据 */ @Override public

  • Domon
    Domon
1 min read
Android

Android全屏幕隐藏NavigationBar

有时候针对一个视频播放页面,需要将NavigationBar隐藏掉,这样有更加好的用户体验。我最近在做ExoPlayer相关的一个视频播放的需求,发现默认情况下,这个Player是没有隐藏掉NavigationBar的,这就导致了在点击屏幕暂停播放的时候,会拉伸缩放视频比例,上下留有黑边。等到NavigationBar被隐藏的时候,视频又会重新填充进整个屏幕。体验不是很好,所以需要改造一下NavigationBar。 原理很简单,就是通过获取getWindow().getDecorView(),然后设置setSystemUiVisibility就可以实现。但是要注意API版本,直接看代码片段。 protected void hideBottomUIMenu(){ if (Build.VERSION.SDK_INT > 11 && Build.VERSION.

  • Domon
    Domon
1 min read
Android

截取部分Url链接

早上做一个Feature的时候,需要这样的一个操作,将给定的一个URL字符串,转换成Application中的Path路径,方便Router做跳转。最开始我是打算通过正则来去写的,最后想一想普通的String转换就能做到。假设输入路径为https://www.google.com/testUrl/ThisisatestHttps://www.google.cn/notatallhttp://www.baidu.com预期想要得到的结果为/testUrl/Thisisatest/notatall/代码很简单,如下private String convertUrlToPath(String url) { url = url.substring(url.

  • Domon
    Domon
1 min read
Android

Android Handler使用

在Android开发的过程中,经常会有这样的场景:从网络获取数据然后更改某个控件的属性。例如,从网络API获取Json,解析某个字段的值,将它设定到对应的TextView中。在很多人刚开始入门Android的时候,可能会将网络请求解析和设定TextView放在一起处理。当然这样是不行的。为什么呢?这个就需要引入线程和进程的概念。 进程和线程 说到进程,其实是需要大致了解一些计算机的CPU原理的。CPU是一台电脑的处理核心,假设现在的CPU是单核的,所有的任务处理都是需要通过它来进行的。它通过时间将任务分成一个又一个的时间片进行处理。对我们用户来看,好像上网、听歌、处理Word好像是一直都在运行。但对于CPU来说,它可能处理了一会上网的任务,又处理了一会听歌的任务,然后又处理了一下Word的任务。因为CPU速度很快,现在操作系统也有很好的调度策略。导致对于我们用户来说,好像任何的任务都是连续不间断的。上面所说的上网、听歌、

  • Domon
    Domon
5 min read
Android

智能电视Root并删除预装

自从不怎么玩Xbox了之后,一直都没有怎么用过电视,基本上大的需求就是把NAS里面的电影有的时候在电视上面放着看看。每次开机都被我家这个海信智能电视的广告恶心到了。说好的智能也就是在Android系统开机之前放一个15~30s不等的广告。 想一想,既然都是Android系统了,那么就很简单了,Root后我找到对应的预装软件删除了就好了。 环境信息 智能电视:海信K370 工具:一台电脑,一个外接USB键盘 前提:保证电脑中ADB已经配置好了,同时电脑和电视在一个局域网 开始 打开电视的ADB调试模式 这里面每个品牌的智能电视都不一样,像海信不同型号的方式也不同。具体的大家可以自行电视型号+工厂模式就可以搜出来。我的这台电视机,需要在**「设置-声音-声音平衡」的这个选项中,通过外接键盘输入1969**,此时屏幕右上角就会出来一个黄色背景的M,按遥控器的菜单键,就可以呼出工厂模式的菜单了。

  • Domon
    Domon
3 min read
Android

RcyclerView DataBinding结合

最近在将自己之前的项目从MVP更改到MVVM,遇到了一些坑,也学习了不少。记录下自己怎么去解决RcyclerView和DataBinding结合的过程。本文的前提是假设你有一部分的MVVM的基础,并且知道如何是用DataBinding。 重点 先说重点,RcyclerView和DataBinding结合最重要的其实就两个方法: onCreateViewHolder()中ViewHolder获取了对View的引用,方便快速的处理数据 onBindViewHolder()中将指定的数据传送给View 实现 为了达到通用的目的,我创建了一个基础的Adapter。按照上面说的两个重要方法。我们看看如何实现: onCreateViewHolder() @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { B binding = DataBindingUtil.inflate(

  • Domon
    Domon
3 min read
Android

Android签名信息获取

由于接手一个二次项目,需要更改一下之前的签名信息,但是发现签名信息修改之后,程序中出了很多问题,跟踪了下,发现是接入第三方平台服务过程中,签名信息不一致导致的。 可以在命令行中输入 keytool -v -list -keystore yourkeystore 之后会有这么一串信息输出 别名: test 创建日期: 2017-11-13 条目类型: PrivateKeyEntry 证书链长度: 1 证书[1]: 所有者: 发布者: 序列号: 有效期开始日期: Mon Nov 13 16:57:

  • Domon
    Domon
1 min read
Android

更新AS导致界面预览失效

今天在更新自己笔记本的AS时候,遇到了一个问题。首先打开Layout文件,没法预览布局。 按照网上说的,我将我自己的SDK版本做了勾选,仍然无法使用。 使用了无数次的Restart and invalidate caches 仍然没有效果。反倒Run 那一栏全部灰掉。找寻了很久没有找到很好的解决方案。 看到Log输出的结果是这样: Write access is allowed from event dispatch thread only 顺着这个思路,看到了SOF上面有一个开发者提供了一个解决方案,试了试。成功。 原因就是在AS 3.0RC 版本升级到AS

  • Domon
    Domon
1 min read
Android

同时安装Release和Debug版本

在开发的过程中,由于经常切换开发环境和线上环境,对应的开发出来的包也是Debug和Release两个版本。由于Android只允许一台手机安装包名唯一的APP,所以难免在切换环境的时候,来回的删除再安装。 原理 为了想解决这个问题,昨天我着手将自己的APP配置了下,已经完美可以实现两个版本共存了。用到的,其实是Gradle的灵活性。 既然上面已经说了,Android系统默认只能安装一个包名相同的APP,那要想同时安装两个APP,所要做的操作就很简单了。让Debug和Release产生出不一样的包名就可以搞定。 实现 顺着这个思路,我们只需要利用Gradle的特性就可以完成。在默认的情况,我们是可以通过Gradle配置来实现分版本打包签名。 `android{ signingConfigs { debug { } release { storeFile file(“x.keystore") storePassword “x”

  • Domon
    Domon
2 min read
Android

关于Toolbar的Back返回问题

昨天在引入Toolbar的时候,出现了一个问题。就是按Toolbar上面的back按钮没有反应。实际上点击时间是发生的,因为产生了动画。 同样另一个Activity,也是用了同样设置方法,确是可行的,我觉得很奇怪,看了看两者的区别,初始化的时候代码都一样 setSupportActionBar(mToolbar); getSupportActionBar.setDisplayHomeAsUpEnabled(true); 找来找去,都觉得很奇怪,去SOF搜了下,这里有一个解答。 其实一下子转眼一想,也就明白了为什么会这样。Toolbar上的按钮「无论是自定义的还是系统实现的」实际上都是需要在**onOptionItemSelected(MenuItem item)**中来处理选择后的逻辑。因此,这里需要将Toolbar中的back事件处理下。即 @Override

  • Domon
    Domon
1 min read
Android

ButterKnife in BaseActivity and BaseFragment

在日常的开发中,我们经常会遇到这样的场景,几个比较特定的功能或者重复的代码在Activity/Fragment中,我们一般采取的措施就是抽离出来去做一个基类,然后通过子类继承父类的方式来实现。 对于用过ButterKnife的朋友来说,应该已经体会到BF的便捷性和优点。所以理所当然,我们需要把BF放到BaseClass中,节省书写重复代码。 但正如这个issue中JakeWharton说的那样: Gotcha. Butter Knife is not magical and is actually a very boring, stupid, and predicable library. If you call Butter Knife

  • Domon
    Domon
1 min read
Android

Google TODO-MVP详解

简单介绍在日常的开发当中,经常会遇到需求的变动。这个东西是真的难以避免的,所以对于产品的基础框架就比较重要了。Google大大在I/O大会上提出来了Android开发方式是属于MVP的,即Model+View+Presenter。另外在GitHub上面放出来了一个样例,供开发者学习,这里可以看到整个项目的简介。Google通过一个TODO类的APP讲解了如何使用一些第三方库,已经如何基于他们构建自己的APP的框架。目前的状态Stable samplesSampleDescriptiontodo‑mvpDemonstrates a basic Model‑View‑Presenter (MVP) architecture and provides a foundation on which the other samples

  • Domon
    Domon
8 min read
Android

如何自定义View

首先奉上AndroodDeveloper的教程。 假设我们以自定义一个View,实现圆形的按钮功能。 说一下简单的流程: 继承View 重写构造函数 重写OnMeasure()方法 重写OnDraw()方法 配置XML 我把配置XML放到最后不是因为需要最后去处理,而是它相对来说比较独立。 继承View,重写构造函数 首先重写View的构造函数 private CustomView (Context context){ this(context,null); } private CustomView(Context context, AttributeSet attrs){ this(context,attrs,0)

  • Domon
    Domon
7 min read
Android

Data Binding(四):事件监听

在之前的文章里,我写了如何在Android App中如何消除FindViewById(),同时解决View IDs的问题。有一件事情是我没有在之前文章中显示出来,即如何处理事件监听,例如View’s OnClickListener和TextView’s TextWatcher。 Android Data Binding 提供了三种在布局文件中设置事件监听的机制,你可以选择最适合你的方法。不同于基础的Android OnClick属性,在data binding的实践机制中没有使用反射,所以不论你选择哪一种方法都不会去影响性能。 Listener Objects 在任何一个可以使用set* 调用的listener(并不是add *调用的)的view中,你都可以绑定一个listener到它的属性上。如下: <View

  • Domon
    Domon
4 min read
Android

Retrofit获取网络Dom数据

前两天在一个小事情上面卡壳好久,需求是这样的,我想通过jsoup去解析一个数据源。通过Retrofit处理这个请求,但是一直会出问题。单步调试才发现问题的所在,response.body()中的数据并不是我想要的。我比较需要response.body().raw()里面的数据,但是官方没有这个方法获取。愁的我继续看官方的API,后面才发现,需要这样将response.body().toString()改成response.body().string(),万事大吉。得到了我需要的网页源数据。

  • Domon
    Domon
1 min read
Android

Data-Binding(三):让View-Id不再那么必要

你是否有在看别人的布局时候,然后想「这些值哪里进行的get&set」。或者你觉得消除findViewById是伟大的第一步,但是这里还是有很多的样板代码。Android Data Binding 使得这些事情变得简单。 使用ViewHolder模式 比方说我想在我们的应用程序中展示用户的信息。在不要再使用findViewById,我展示了通过AS生成一个ViewHolder模式的类,布局文件如下: *user_info.xml* <?xml version="1.0" encoding="utf-8"?> <layout xmlns:

  • Domon
    Domon
5 min read