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"/>
復制代碼
總結
以上是生活随笔為你收集整理的java tag和flt区别,这些年,我爬过的 Android 坑 | 持续更新的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php表单写入数据库,php表单写入数据
- 下一篇: android辅助功能模拟home键,A