动态更改片段后,Viewpager滑动aint即可工作

时间:2019-04-15 01:58:00

标签: android android-fragments android-asynctask android-viewpager

当我尝试在viewpager中动态切换(而不是使用FragmentTransaction替换)片段时,出现了我遇到的问题。 该viewpager在其他viewpager内部,但这不是问题。 它使用ViewPagerStateAdapter也可以正常工作。

现在,当打开此viewpager父片段时,滑动功能将关闭。必须执行一种方法,这会导致滑动解锁。

当我在单击按钮时执行此特定方法时,在片段之间滑动会效果良好,流畅且快速。

但是,当从onCreateView()执行的asynctask结果自动执行相同的方法时,则会导致刷卡混乱(非常慢,很难刷卡到下一个/上一个片段)。

这是寻呼机适配器:

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    private final List<ABaseFragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();
    private final List<String> mFragmentTagList = new ArrayList<>();
    private WeakReference<Context> context;
    private int pagerID;
    private FragmentManager fragmentManager;
    private int previous = 0;

    public ViewPagerAdapter(FragmentManager manager, int pagerID, Context ctx) {
        super(manager);
        this.pagerID = pagerID;
        this.fragmentManager = manager;
        this.context = new WeakReference<>(ctx);
    }

    public ViewPagerAdapter(FragmentManager manager, int pagerID) {
        super(manager);
        this.pagerID = pagerID;
        this.fragmentManager = manager;
    }

    @Override
    public ABaseFragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getItemPosition(@NonNull Object object) {
        return POSITION_NONE;
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(ABaseFragment fragment, String title, String tag) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
        mFragmentTagList.add(tag);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }

    public String getPageTag(int position) {
        return mFragmentTagList.get(position);
    }

    public ABaseFragment getPageFragmentByPosition(int position) {
        return mFragmentList.get(position);
    }

    public ABaseFragment getPageFragmentByTag(String fragTag) {
        return mFragmentList.get(mFragmentTagList.indexOf(fragTag));
    }

    public int getPagePositionByTag(String fragmentTag) {
        return mFragmentTagList.indexOf(fragmentTag);
    }

    public ABaseFragment getPageFragmentByClass(String fragClassName) {
        if (fragClassName != null && !fragClassName.trim().isEmpty())
            for (ABaseFragment pagerFragment : mFragmentList) {
                if (pagerFragment.getClass().getName().trim().equals(fragClassName.trim()))
                    return pagerFragment;
            }
        return null;
    }

    public void onPageChanged(int position) {
        // logic when viewpager page changes here...

        previous = position;
    }
}

这是动态切换片段的方式:

public void switchPagerFragment(String fragmentTag) {
    pager.setCurrentItem(pagerAdapter.getPagePositionByTag(fragmentTag));
    pagerAdapter.notifyDataSetChanged();
}

这是viewpager中的第一个片段,它执行asynctask,结果执行方法,然后导致刷卡解锁

public class ParamsFragment extends ABaseFragment implements IBackPressCallback {

    /**
     * This method will only be called once when the retained
     * Fragment is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Retain this fragment across configuration changes.
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_params, container, false);
        relativeDummy = (RelativeLayout) rootView.findViewById(R.id.layParamsDummy);

        executeTask();

        return rootView;
    }

    private void executeTask() {
        DateRequest request = new DateRequest();
        request.setParams(params);
        task = new DateTask();
        task.setResultHandler(callback);
        task = (AbstractTask<DateRequest, DateResponse>) task
                .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, request);
    }

    public void updateSwipe(boolean working) {
        // here try to unlock the swipe
        swipeable = working;
        if (pager != null)
            pager.setSwipeable(swipeable);
    }

    // CALLBACKS
    private TaskResultHandler<DateResponse> callback = new TaskResultHandler<DateResponse>() {
        @Override
        public void handle(final DateResponse result, final Exception ex) {
            if (result != null) {
                updateSwipe(true);
                ((MainActivity) setupActivity().get()).switchPagerFragment(Consts.TAG_FRAG_TOTALS);
            } else
                Toast.makeText(setupActivity().get(), "date task error", Toast.LENGTH_LONG).show();
        }
    };
}

这是我自定义的无滑动寻呼机:

public class SwipelessPager extends ViewPager {

    private Boolean swipeable = true;

    public SwipelessPager(Context context) {
        super(context);
    }

    public SwipelessPager(Context context, AttributeSet attrs){
        super(context,attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return swipeable ? super.onInterceptTouchEvent(event) : false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return swipeable ? super.onTouchEvent(event) : false;
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        return swipeable ? super.canScrollHorizontally(direction) : false;
    }

    public void setSwipeable(Boolean swipeable){
        //When swipeable = false not work the scroll and when swipeable = true work the scroll
        this.swipeable = swipeable;
    }

    public Boolean getSwipeable() {
        return swipeable;
    }
}

当我在某些按钮单击侦听器中调用updateSwipe()时,一切都将顺利进行并且很好。

我认为这可能与用户界面有关。 因此,我将这种方法封装如下:

public void updateSwipe(boolean working) {
    setupActivity().get().runOnUiThread(new Runnable() {
        swipeable = working;
        if (pager != null)
            pager.setSwipeable(swipeable);
    });
}

它没有帮助。

1 个答案:

答案 0 :(得分:0)

事实证明,片段的onCreateView()是调用executeTask()的错误位置。

相反,应从片段的onAttach()调用它。

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    if(pager != null)
        pager.setSwipeable(swipeable);

    executeTask();
}

/**
 * Set the callback to null so we don't accidentally leak the
 * Activity instance.
 */
@Override
public void onDetach() {
    super.onDetach();

    if (task != null && task.getStatus() == AsyncTask.Status.RUNNING)
        task.cancel(true);
    task = null;
}