Fragment anti-tremor best practices

Article Directory
  • At last
  • Original link: http://www.jianshu.com/p/9dbb03203fbc

    Stabilize: prevent users tremor, many times in rapid succession with a button click.

    Why do I need anti-tremor treatment?

    During the jump between Fragment (v4), the following two situations can lead to a poor user experience :( Go to AFragment BFragment for example)

    1, BFragment not really create (because the transaction is not Fragment start immediately), you tremor under 2 points, there will be a one-time start two BFragment;

    2, in the jump BFragment process, if there is a transition animation, at any time before the end of the animation, you click on a region BFragment clickable page, click on the area of ​​the event will be triggered.

    Without any anti-tremor treatment, you may encounter situations GIF below:

    No anti-tremor treatment

    So for Fragment be anti-tremor treatment is still very necessary, RxJava series Rxbinding package can help you solve the problem, debounce operator can achieve anti-tremor, but a lot of cases, you will use RxJava but do not want to use Rxbinding.

    In fact, no matter what kind of program, I think you are not willing to deal with all the manual once judder issues in each event click in.

    We need a base class package, can solve the problem of anti-shake, and do not have to be anti-shake button to start the process in each of the Fragment.

    Common program

    There is one kind of common anti-tremor treatment: by the time difference

          
          
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
          
          
    private static final long DEBOUNCE_TIME = 300L;
    private long mCurrentTime;
    private void addFragment(Fragment fragment) {
    long time = System.currentTimeMillis();
    if (time - mCurrentTime < DEBOUNCE_TIME) {
    return;
    }
    mCurrentTime = time;
    getSupportFragmentManager().beginTransaction()
    .add(R.id.fl_container, fragment, fragment.getClass().getSimpleName()) // replace亦一样
    .... omitted animation set to join the fallback stack, etc.
    }

    Although this method can achieve the effect of anti-shake, but the applicability is limited;
    for example, if I need to add a Fragment, then followed by the immediate need and Fragment Fragment add a sub, then add sub Fragment of operation might be the time difference is masked.

    My program

    In view of the above-described binding process, is combined with a host Fragment Activity, I have the following protocol:
    using the Activity dispatchTouchEvent(MotionEvent ev)method.

    General idea is that after clicking immediately to intercept everything Activity Touch event, at the end of the transition animation target Fragment (if no transition animations, it is after onActivityCreated is called), let Activity unblocked.

    Next we will look at the specifics of how to achieve it!

    In BaseActivity in:
          
          
    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;
    }
    return super.disp 大专栏   Fragment防手抖 最佳实践atchTouchEvent(ev);
    }
    /**
    * 控制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);
    // processing without transition animation
    if (! mEnterAnimFlag) {
    mActivity.allowFragmentClickable(true);
    }
    }
    }

    When Fragment initialization sequence of their life cycle:
    ... -> onCreateView -> onCreateAnimation -> onActivityCreated

    Thus the life cycle, combined with comments on the code, I believe you understand at a glance ~

    Finally, the use of Android event distribution mechanism, using less than 50 lines of code perfect solution to handle Fragment of anti-tremor.
    Finally, look at the effect of:

    Anti-tremor

    To get more details or depth Fragment optimization using Fragment of a small partner, I recommend a look at this Fragmentation library


    Shall not be reproduced without permission, please indicate the zilianliuxue the blog, I All Rights Reserved.

    Guess you like

    Origin www.cnblogs.com/liuzhongrong/p/11874910.html