オリジナルリンク:http://www.jianshu.com/p/9dbb03203fbc
安定化:ボタンのクリックで矢継ぎ早のユーザー振戦、何回も防ぎます。
なぜ私は抗振戦の治療が必要なのでしょうか?
フラグメント(V4)の間のジャンプ中に、次の2つの状況が悪いユーザーエクスペリエンス例えばAFragment BFragmentへ:(ゴー)につながることができます
1、BFragmentは本当に作成(トランザクションではないので、すぐに開始フラグメント)、あなた振戦2ポイントの下で、2 BFragmentを開始一時間があるでしょうではありません。
2、ジャンプBFragmentプロセスでは、トランジションアニメーションがある場合は、アニメーションの終了前であればいつでも、あなたは、地域のBFragmentクリッカブルページをクリックしてイベントのエリアをクリックしてトリガされます。
任意の抗振戦の治療がなければ、あなたは下のような状況のGIFを発生することがあります。
いいえ抗振戦治療ません
だから、フラグメントのための抗振戦の治療は依然として非常に必要であること、パッケージをRxbinding RxJavaシリーズは、デバウンスオペレータは抗振戦を達成することができ、あなたは問題を解決するのに役立つことができますが、多くのケースでは、あなたはRxJavaを使用しますが、Rxbindingを使用する必要はありません。
実際には、プログラムの関係なく、どのような、私はあなたが各イベントのクリックでジャダーの問題いったんすべてのマニュアルを扱うことを望んでいないと思います。
私たちは、手ぶれ補正の問題を解決することができ、およびフラグメントの各プロセスを開始するには手ぶれ補正ボタンである必要はありません、基本クラスのパッケージが必要です。
一般的なプログラム
一般的な抗振戦の治療の一種があります:時間差によって
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
プライベート静的最終長いDEBOUNCE_TIME = 300L;
プライベート長いmCurrentTime。
プライベートボイドaddFragment(フラグメント断片){
長い時間=にSystem.currentTimeMillis();
IF(時間 - mCurrentTime <DEBOUNCE_TIME){
リターン;
}
mCurrentTimeは時間を=。
getSupportFragmentManager()。のbeginTransaction()
.add(R.id.fl_container、フラグメント、fragment.getClass()。getSimpleName())//亦置き換える一样
フォールバックスタックに参加するように設定....省略アニメーションなど
}
|
この方法は、手ぶれ補正の効果を得ることができますが、適用性が制限されているが、
私はフラグメントを追加する必要がある場合、たとえば、その後、すぐに必要とフラグメントフラグメントに続いてサブを追加し、操作の追加サブフラグメントがあるかもしれません時間差がマスクされています。
マイプログラム
上記結合プロセスの観点から、ホストフラグメント活動と結合され、Iは、以下のプロトコルを持っている:
アクティビティ使用dispatchTouchEvent(MotionEvent ev)
方法。
一般的な考え方は、インターセプトのすべての活動のタッチイベントに即座にクリックした後、遷移アニメーションターゲットフラグメント(無遷移アニメーション場合onActivityCreatedが呼び出された後、それはある)の終わりに、活動がブロック解除させていること。
次に我々はそれを達成する方法の詳細を見ていきます!
中BaseActivityで:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public class BaseActivity extends AppCompatActivity {
private boolean mAllowClickable = true;
@Override
public boolean dispatchTouchEvent(MotionEvent event){
// 防抖动(防止点击速度过快)
if (!mFragmentClickable) {
return true;
}
}
/**
* 控制Activity是否拦截Touch事件
*/
public void allowFragmentClickable(boolean clickable){
mAllowClickable = clickable;
}
/**
* 加载Fragment (replace同理)
*/
private void addFragment(Fragment fragment) {
// 启动Fragment时,Activity拦截一切Touch事件
allowFragmentClickable(false);
getSupportFragmentManager().beginTransaction()
.add(R.id.fl_container, fragment, fragment.getClass().getSimpleName()) // replace亦一样
....省略设置动画 加入回退栈等
}
@Override
public void onBackPressed() {
// 这里是防止动画过程中,按返回键取消加载Fragment
if(!mAllowClickable){
setFragmentClickable(true);
}
super.onBackPressed();
}
}
|
所有Activity中的Touch事件,首先都需要经过Activity的dispatchTouchEvent
方法,该方法通过Window分发Touch事件,如果返回true,则不再往下层分发,这时我们布局内的任何Touch事件都会“无效”。
在通过Activity来加载Fragment时,将mAllowClickable设为false,此时只到为true时,屏幕的Touch事件将都无效。
在BaseFragment中:
这里将有转场动画和无转场动画两种情况都进行了防手抖处理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class BaseFragment extends Fragment {
// 记录是否有转场动画
private boolean mEnterAnimFlag = false;
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if (enter && nextAnim != 0) {
// 记录 有转场动画
mEnterAnimFlag = true;
Animation anim = AnimationUtils.loadAnimation(mActivity, nextAnim);
mNoAnim.setAnimationListener(new Animation.AnimationListener() {
...省略
@Override
public void onAnimationEnd(Animation animation) {
// 转场动画结束时,允许Touch事件
mActivity.allowFragmentClickable(true);
}
});
}
return super.onCreateAnimation(transit, enter, nextAnim);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//遷移アニメーションなく処理
(もし!mEnterAnimFlag){
mActivity.allowFragmentClickable(真の);
}
}
}
|
そのライフサイクルのときフラグメントの初期化シーケンス:
... - > onCreateView - > onCreateAnimation - > onActivityCreated
したがって、ライフサイクル、コード上のコメントと合わせて、私は〜あなたが一目で理解して信じています
最後に、コードの完璧なソリューション未満の50行を使用してAndroidのイベント分配機構の使用は、抗振戦の断片を処理します。
最後に、の効果を見て:
抗振戦
詳細や小さなパートナーの断片を使用して、奥行きフラグメントの最適化を得るために、私はこれを見てお勧めしますフラグメンテーションライブラリー
許可なしに複製してはならない、zilianliuxueにブログ、私のすべての権利予約を明記してください。