Search code examples
androidandroid-viewpagerontouch

Viewpager PageTranformer blocks UI changes onclick in some devices


I have used Custom ViewPager which extends Viewpager . I have used gesture detector to do the scroll event.

here is my code,

public class VerticalViewPager extends ViewPager {
    private GestureDetector gestureDetector;
    public boolean isScrollEvent;
    public VerticalViewPager(Context context) {
        super(context);
        init();
    }

    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        gestureDetector=new GestureDetector(getContext(),new GestureListener());
        setPageTransformer(true, new VerticalPageTransformer());
        setOverScrollMode(OVER_SCROLL_NEVER);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean res=gestureDetector.onTouchEvent((ev));
        Log.d("event", "interceotontouch      " + res);
        return res;

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean res= gestureDetector.onTouchEvent((ev));
        if((ev.getAction() == MotionEvent.ACTION_CANCEL ||ev.getAction()==MotionEvent.ACTION_UP)) {
            if(isScrollEvent) {
                try {
                    endFakeDrag();
                } catch (Exception e) {}
            }
            return true;
        }
        Log.d("event", "ontouch      "+res);
        return res;
    }

    public void setScrollDuration(int duration) {
        mScroller.setScrollDuration(duration);
    }




    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            isScrollEvent=false;
           Log.d("touch","singletap");
            return false;
        }
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
           Log.d("touch","fling");
            isScrollEvent=false;
            try {
                float diffY = e2.getY() - e1.getY();
                if (diffY > 20) {
                    onSwipeDown();
                    return  false;
                } else if(diffY<-20){
                    onSwipeUp();
                    return  false;
                }
                else
                {
                    endFakeDrag();
                    int id = getCurrentItem();
                    setCurrentItem(id, true);
                }


            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return false;

        }
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
         Log.d("touch", "scroll" + " " + distanceX);
            beginFakeDrag();
            fakeDragBy(-distanceY);
            isScrollEvent=true;
            return true;

        }
    }
    public void onSwipeUp() {
        setCurrentItem(getCurrentItem() + 1);

    }
    public void onSwipeDown() {
        setCurrentItem(getCurrentItem() - 1);

    }
}

And this is my PageTranformer,

public class VerticalPageTransformer implements android.support.v4.view.ViewPager.PageTransformer {
    @Override
    public void transformPage(View view, float position) {
        final float MIN_SCALE = 0.85f;
         final float MIN_ALPHA = 0.5f;

                if (position < -1) {
                    view.setAlpha(0);
                } else if (position <= 0) { // [-1,0]
                    view.setAlpha(1);
                    view.setTranslationX(-1 * view.getWidth() * position);
                    float yPosition = position * view.getHeight();
                    view.setTranslationY(yPosition);
                    view.setScaleX(1);
                    view.setScaleY(1);
                } else if (position <= 1) { // (0,1]
                    view.setAlpha(1 - position);
                    view.setTranslationX(-1 * view.getWidth() * position);
                    float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
                    view.setScaleX(scaleFactor);
                    view.setScaleY(scaleFactor);
                } else {
                    view.setAlpha(0);
                }
    }

}

Everything works fine. But the problem is , When I click something in the current page, onClick() event invoked. But it doesn't update the view. The view gets updated after changing the page.

This is my adapter,

public class MainViewPagerAdapter extends PagerAdapter {

    private Context context;
    private List<NHBean> newslist = new ArrayList<>();
    ImageLoader imageLoader;
    List<String> list = new ArrayList<String>();
    SharedPreferences preferences;
    SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat displayFormat = new SimpleDateFormat("MMM dd, hh:mm a");
    public MainViewPagerAdapter(Context context) {
        this.context = context;
        preferences = context.getSharedPreferences("NewsUpdatePref", Context.MODE_PRIVATE);
        imageLoader = new ImageLoader(context);
        String serialized = preferences.getString("BOOKMARKS", null);
        if (serialized != null)
            list.addAll(Arrays.asList(TextUtils.split(serialized, ",")));

    }

    public void addItems(List<NHBean> newslist) {
        this.newslist.clear();
        this.newslist.addAll(newslist);
        notifyDataSetChanged();
    }

    @Override
    public Object instantiateItem(final ViewGroup collection, int position) {
        LayoutInflater inflater = LayoutInflater.from(context);
        final NHBean nhBean = newslist.get(position);
        Log.d("ImageURL"+position,nhBean.getImageUrl());
        ViewGroup layout;
        layout= (ViewGroup) inflater.inflate(R.layout.page, collection, false);


        TextView text = (TextView) layout.findViewById(R.id.text);
        TextView timeText = (TextView) layout.findViewById(R.id.time_text);
        TextView textHead = (TextView) layout.findViewById(R.id.text_head);
        ImageView shareNews = layout. findViewById(R.id.share_news);
        ImageView firstPage = layout. findViewById(R.id.first_page);
        final ImageView bookmark=layout.findViewById(R.id.bookmark);
        firstPage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((MainActivity)context).moveToFirstPage();
            }
        });
        shareNews.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //code for share
                }
            }
        });
        bookmark.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("clicked","yes");
                if (list.contains(nhBean.getDate())) {
                    list.remove(nhBean.getDate());
                    bookmark.setImageResource(R.drawable.bookmark_not_added);
                } else {
                    bookmark.setImageResource(R.drawable.bookmark_added);
                    list.add(nhBean.getDate());
                }
                preferences.edit().putString("BOOKMARKS", TextUtils.join(",", list)).apply();

            }
        });

        try {
            timeText.setText(displayFormat.format(dateTimeFormat.parse(nhBean.getDate())));
        } catch (Exception e) {
        }

       text.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((MainActivity) context).setToolBarVisibility();

            }
        });

        if (list.contains(nhBean.getDate())) {
            bookmark.setImageResource(R.drawable.bookmark_added);
        } else {
            bookmark.setImageResource(R.drawable.bookmark_not_added);
        }
        textHead.setText(nhBean.getHeadline());
        text.setText(nhBean.getContent() + "\n");

        textHead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, WebViewActivity.class);
                intent.putExtra("text_head", nhBean.getHeadline());
                intent.putExtra("news_url", nhBean.getNewsUrl());
                context.startActivity(intent);
            }
        });
        collection.addView(layout);
        return layout;
    }

    @Override
    public void destroyItem(ViewGroup collection, int position, Object view) {
        collection.removeView((View)view);
    }

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

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public CharSequence getPageTitle(int position) {

        return null;
    }

    public NHBean getItem(int position) {
        return newslist.get(position);
    }


}

When I click these buttons, the onClick() is invoked. Look at bookmark button onclick, setImageResource() is not done. But surprisingly when I scroll, the button image is changed.

Edit:

My MainActivity code,

    mainViewPager = findViewById(R.id.flip_view);
    mainViewPagerAdapter = new MainViewPagerAdapter(this);
    mainViewPager.setAdapter(mainViewPagerAdapter);
    mainViewPager.setScrollDuration(300);
    mainViewPager.addOnPageChangeListener(new VerticalViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

        @Override
        public void onPageSelected(int position) {

            if (position != 0 || !toolbar.getTitle().toString().equals(getString(R.string.allnews))) {
                swipeRefreshLayout.setEnabled(false);
            } else
                swipeRefreshLayout.setEnabled(true);

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
    updateNews();

And the method code,

public void updateNews() {
    try {
        final ArrayList<NHBean> headlines_1 = DBHelper.getInstance(this).getHeadlines();
        mainViewPagerAdapter.addItems(headlines_1);
        swipeRefreshLayout.setRefreshing(false);
    } catch (Throwable e) {
        e.printStackTrace();
    }

}

And also the start animation for each page gets stuck when the page is selected.

Help me !!! Thanks in advance


Solution

  • The problem is not with the code,

    I have used android:hardwareAccelerated="false" in Manifest. After lots of research, I found this.

    I just changed,

    android:hardwareAccelerated="true"
    

    which solved my problem.