您的位置:首页 > 其它

工作日常问题记录与解决 更新日期:2016/1/22

2016-01-22 11:54 323 查看
/# 前言

不重复掉坑里两次

正文

2016/1/22 为RecyclerView添加头,但是头布局为空,导致ViewCompat.canScrollVertically(view,-1)始终返回true。

描述:项目中自定义了下拉刷新控件,模仿着SwipeRefreshLayout写的,行为模式基本一致,在结合RecyclerView使用时出现问题,由于需求需要为RecyclerView添加了一个空的头(只有根布局文件,没有内容),这时候导致在自定义的下拉刷新控件中调用
ViewCompat.canScrolVertically(view,-1)
时,始终返回true,无法出发下拉刷新的事件。

原因:

1,一方面是因为RecyclerView会对空布局,或者是布局中都是Gone的元素,做优化,导致在ViewComapt.conScrollVertically(v,-1)时,始终认为还是可以进行下拉的。

解决:重写RecyclerView的
canScrollVertically()
方法,手动判断第一个孩子的位置,只要
getTop()
大于0,就认为孩子已经显示了。

@Override
public boolean canScrollVertically(int direction) {
if (direction < 1) {
boolean original = super.canScrollVertically(direction);
if (!original || getChildAt(0) != null && getChildAt(0).getTop() >= 0) {
return false;
}else {
return true;
}
}
return super.canScrollVertically(direction);
}


另外,请注意,下面这种方式,无法判断出隐藏的头是否完全显示:

@Nullable
private boolean isFirstCompeteVisible() {
LayoutManager layoutManager = getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
int position = ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition();
return position == 0;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int[] positions = ((StaggeredGridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPositions(null);
for (int position : positions) {
if (position == 0) {
return true;
}
}
}
return false;
}


===========

/**
* 是否还可以上拉
* @return true可以,false不可以
*/
public boolean canChildScrollDown() {
if (android.os.Build.VERSION.SDK_INT < 14) {
return yChildView.getScrollY() > 0;
} else {
return ViewCompat.canScrollVertically(yChildView, 1);
}
}

/**
* 是否还可以下拉
* @return true可以,false不可以
*/
private boolean canChildScrollUp() {
if (android.os.Build.VERSION.SDK_INT < 14) {
return yChildView.getScrollY() > 0;
} else {
return ViewCompat.canScrollVertically(yChildView, -1);
}
}


2015/11/19 超大图片无法通过PhotoView显示

描述:通过PhotoView显示超大图片,宽高像素超过4096。OPGL会报错: Bitmap too large to be uploaded into a texture (299x7200, max=4096x4096)

解决办法:判断是否是大图,然后关闭硬件加速

if (isBigPicture(bitmap)) {
MyPhotoView.this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

public static final int OPGL_MAX_TEXTURE = 4000;

private boolean isBigPicture(Bitmap bitmap) {
//penGLRenderer: Bitmap too large to be uploaded into a texture (299x7200, max=4096x4096)
return bitmap.getHeight() >= OPGL_MAX_TEXTURE || bitmap.getWidth() >= OPGL_MAX_TEXTURE;
}


2015/10/29 EditText自动抢占焦点,弹出输入法

描述:当第三方分享取消或者结束时,回到拥有EditText控件的页面,自动弹出输入法。

解决:在EditText控件以外的地方,单独设置一个空布局抢占焦点。

使用
focusable=true
focusableInTouchMode=true


代码如下:

<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="horizontal" />

<RelativeLayout
......>

<TextView
......
android:text="发送"
android:textColor="@color/ffe707" />

<EditText
......
android:hint="说点什么吧..."/>
</RelativeLayout>


2015/10/29 点击非EditText区域,自动收回输入法

描述:点击非EditText区域时,不自动收回输入法。

解决:在
Activity
中重写
dispatchTouchEvent
方法,不拦截
EditText
的触摸事件,非
EditText
区域时手动收回输入法。

如果
EditText
旁有发送按钮,那么也需要让其能够响应事件。

代码如下:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
/**
* 点击非EditText区域,隐藏键盘
*/
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideInput(v, ev)) {

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
return super.dispatchTouchEvent(ev);
}
// 必不可少,否则所有的组件都不会有TouchEvent了
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}

public boolean isShouldHideInput(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] leftTop = {0, 0};
//获取输入框当前的location位置
v.getLocationInWindow(leftTop);
int left = leftTop[0];
int top = leftTop[1];
int bottom = top + v.getHeight();
int right = left + v.getWidth();

int width = Utils.getScreenWidth();

if (event.getX() > left && event.getX() < width
&& event.getY() > top && event.getY() < bottom) {
// 点击的是输入框区域,保留点击EditText的事件
return false;
} else {
((EditText) v).clearFocus();
return true;
}
}
return false;
}


学习方向及目标

目标一:写完分析Fresco基础体系的博客

目标二:重构公司项目的Fresco使用体系

目标三:开源重构后的代码,并结合实例写几篇博客。

目标四:Drawable体系的分析和使用

如何学习

知道一个框架解决的问题是什么,比如说fresco,就是用于图片加载,并且知道他的优缺点是什么

感觉这个框架适合你或者说吸引你,试用一下,写下demo

如果有官方介绍更好,将官网的介绍以及实现的原理或者架构分层学习一下

翻看对应的框架源码学习,翻看源码分析的过程手头可以参照以下的思路,其实翻看源码,从程序调用的入口点作为突破口,关键的内容做笔记,遵循先广度后深度的方式便可 ,另外,阅读复杂的框架,肯定是一遍吃不消的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: