java tag和flt区别,这些年,我爬过的 Android 坑 | 持续更新
如何理解非主线程可以更新UI
谷歌在 viewRootImpl 中检查更新ui的线程
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
复制代码
在执行onCreate的时候这个判断并没有执行到
dialogFragment 全屏时左右留空的解决方案
在 fragment#onResume 中重新调整 window 布局
android.view.WindowManager.LayoutParams lp = window.getAttributes();
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(lp);
复制代码
dialogFragment 全屏时状态栏出现黑色布局的解决方案
在主题中设置
true
复制代码
此时 window 为 wrap_content,如果出现左右空白,则考虑使用上个问题的方案。
recyclerview 调用 notifyItemRemoved 方法移除某个 Item 之后因为引用 position 引起 crash 的原因
`notifyItemRemoved`方法并不会移除列表的数据源的数据项导致数据源中的数据与列表Item数目不一致,需要同步刷新数据源。
recyclerview 局部刷新Item时会因为默认动画导致闪烁的解决方案
因为recyclerview存在ItemAnimator,且在删除/更新/插入Item时会触发,可设置不支持该动画即可。
((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
复制代码
recyclerview 中的 item 出现莫名的偏移滚动
这个问题经过定位存在于 viewholder 中的某个 view 可能提前获取到焦点。 同时在。alibaba-vlayout 库中也发现有人反馈改问题。 issues-255 解决的方法是在 Recyclerview中外层父布局中添加 android:descendantFocusability="blocksDescendants" 用于父布局覆盖 Recyclerview 优先抢占焦点。
recyclerview 内容超过一屏时,findFistCompletelyVisibleItemPosition 会返回 -1 的原因
原因是在 findOneVisibleChild 计算出来的 start 和 end 已经超过了 reclclerview 的 start 和 end.经过研究源码得到以下。
findFirstCompletelyVisibleItemPosition -> -1
findLastCompletelyVisibleItemPosition -> -1
findFirstVisibleItemPosition -> 正常
findLast
复制代码
textview 中富文本点击事件拦截了长按事件的解决方案
这个问题常见于消息列表中,某条消息使用了ClickableSpan用于处理富媒体的点击事件,同时这个消息又需要支持长按复制。由于LinkMovementMethod方法在onTouchEvent一直返回true,可以通过自定义View.onTouchListener来替换setMovenmentMethod达到效果。
public class ClickMovementMethod implements View.OnTouchListener {
private LongClickCallback longClickCallback;
public static ClickMovementMethod newInstance() {
return new ClickMovementMethod();
}
@Override
public boolean onTouch(final View v, MotionEvent event) {
if (longClickCallback == null) {
longClickCallback = new LongClickCallback(v);
}
TextView widget = (TextView) v;
// MovementMethod设为空,防止消费长按事件
widget.setMovementMethod(null);
CharSequence text = widget.getText();
Spannable spannable = Spannable.Factory.getInstance().newSpannable(text);
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = spannable.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_DOWN) {
v.postDelayed(longClickCallback, ViewConfiguration.getLongPressTimeout());
} else {
v.removeCallbacks(longClickCallback);
link[0].onClick(widget);
}
return true;
}
} else if (action == MotionEvent.ACTION_CANCEL) {
v.removeCallbacks(longClickCallback);
}
return false;
}
private static class LongClickCallback implements Runnable {
private View view;
LongClickCallback(View view) {
this.view = view;
}
@Override
public void run() {
// 找到能够消费长按事件的View
View v = view;
boolean consumed = v.performLongClick();
while (!consumed) {
v = (View) v.getParent();
if (v == null) {
break;
}
consumed = v.performLongClick();
}
}
}
}
textView.setOnTouchListener(ClickMovementMethod.newInstance());
复制代码
如何禁止 ViewPager 的滑动
重写ViewPager onTouchEvent 和 onInterceptTouchEvent 并返回false,不处理任何滑动事件
@Override
public boolean onTouchEvent(MotionEvent arg0) {
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return false;
}
复制代码
如何仿蘑菇街/马蜂窝 Viewpager 装载图片之后切换时动态变更高度
imageViewPager 为普通的 Viewpager 对象
imageListInfo为存放图片信息的list,imageShowHeight为业务需要显示高度,通过切换时动态计算调整
imageViewPager.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
imageViewPager.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//根据viewpager的高度,拉伸显示图片的宽度调整高度。
ViewGroup.LayoutParams layoutParams = imageViewPager.getLayoutParams();
layoutParams.height = imageListInfo.imageShowHeight[0];
imageViewPager.setLayoutParams(layoutParams);
}
});
imageViewPager.setAdapter(imagePagerAdapter);
imageViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (position == imageListInfo.getImageListSize() - 1) {
return;
}
int height = (int) (imageListInfo.imageShowHeight[position] * (1 - positionOffset) + imageListInfo.imageShowHeight[position + 1] * positionOffset);
ViewGroup.LayoutParams params = imageViewPager.getLayoutParams();
params.height = height;
imageViewPager.setLayoutParams(params);
}
@Override
public void onPageSelected(int position) {
if (!clickListBySelf) {
toSelectIndex(imageListInfo.selected, position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
复制代码
如何控制 appbarLayout 随时定位到某个位置
```
CoordinatorLayout.Behavior behavior =((CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams()).getBehavior();
if (behavior instanceof AppBarLayout.Behavior) {
AppBarLayout.Behavior appBarLayoutBehavior = (AppBarLayout.Behavior) behavior;
int topAndBottomOffset = appBarLayoutBehavior.getTopAndBottomOffset();
if (topAndBottomOffset != 0) {
appBarLayoutBehavior.setTopAndBottomOffset(0);
}
```
如何禁止 appbarLayout 滚动
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false;
}
});
复制代码
edittext 未能响应 onClickListener 事件的解决方案
Edittext监听未获取焦点的Edittext的点击事件,第一次点击触发OnFocusChangeListener,在获取焦点的情况下才能响应onClickListener
使用 listview 或gridview 的处理 item 的 state_selected 事件是无效的解决方案
在xml布局中对listview或gridview设置Android:choiceMode="singleChoice",并使用state_activated状态来代替state_selected状态。(2016.12.10)
解决5.0以上Button自带阴影效果的方案
在xml定义的Button中,添加以下样式定义
style="?android:attr/borderlessButtonStyle"
复制代码
针对 onSingleTapUp 和 onSIngleTapConfirmed 的使用区别
前者在按下并抬起时发生,后者有一个附加条件时Android会确保点击之后在短时间内没有再次点击才会触发。常用于如果需要监听单击和双击事件。
如何使用layer-list画三角形
//左
android:fromDegrees="45"
android:pivotX="85%"
android:pivotY="135%">
android:width="16dp"
android:height="16dp" />
//右
android:fromDegrees="45"
android:pivotX="15%"
android:pivotY="-35%">
android:width="16dp"
android:height="16dp" />
//上/正
android:fromDegrees="45"
android:pivotX="-40%"
android:pivotY="80%">
android:width="16dp"
android:height="16dp"/>
//下
android:fromDegrees="45"
android:pivotX="135%"
android:pivotY="15%">
android:width="16dp"
android:height="16dp"/>
复制代码
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
