Android PagerAdapter not reporting correct position if click previous item
Asked Answered
R

4

10

I have a ViewPager w/ negative margins set to get an effect like this: enter image description here

Now, what I want to happen is that when I click on a view to the left or to the right of the current view. It should select that view and call setCurrentItem() on the ViewPager. This works fine with the view to the right of the current item, but not with the view to the left of the current item. When I click on that view, the position that is reported to me is that of the current view.

Here's some code if it helps. This is from PagerAdapter.instantiateItem() where I'm firing on onClick():

    @Override
    public Object instantiateItem(final ViewGroup container, final int position)
    {
        cardLayout.setTag(profile);
        cardLayout.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                // mOnItemClickListener passed in to adapter on initialization
                mOnItemClickListener.onItemClick(null, view, position, 0);
                // other stuff happens here as well
            }
        });
    }

Entire PagerAdapter class for anyone who is interested:

static class GiveTenPagerAdapter extends PagerAdapter
{
    private final int ANIMATION_DURATION;
    private ListenerOnGiveTakeClick mListenerOnGiveTakeClick;
    private List<GiveTen> mGiveTens;
    private Context mContext;
    private LayoutInflater mInflater;

    private boolean mIsCrossFadeAnimationRunning;
    private int mSquarePhotoSideLength;

    GiveTenPagerAdapter(List<GiveTen> giveTens, Context context,
                        ListenerOnGiveTakeClick listenerOnGiveTakeClick)
    {
        mGiveTens = giveTens;
        mContext = context;
        mListenerOnGiveTakeClick = listenerOnGiveTakeClick;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        ANIMATION_DURATION = mContext.getResources().getInteger(android.R.integer.config_mediumAnimTime);
    }

    List<GiveTen> getGiveTens()
    {
        return this.mGiveTens;
    }

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

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

    @Override
    public Object instantiateItem(final ViewGroup container, final int position)
    {
        Logger.d("position=" + position);

        final GiveTen giveTen = mGiveTens.get(position);
        final UserProfile profile = giveTen.getUserProfile();

        final RelativeLayout cardLayout = (RelativeLayout) mInflater.inflate(R.layout.give_ten_card, null);
        final RelativeLayout profilePicLayout = (RelativeLayout) cardLayout.findViewById(R.id.give_ten_profile_pic_layout);
        final ImageView profileImageView = (ImageView) cardLayout.findViewById(R.id.give_ten_profile_pic);
        final View viewFiller = cardLayout.findViewById(R.id.view_filler);
        final int RADIUS = Math.round(mContext.getResources().getDimension(R.dimen.give_ten_card_corner_radius));

        profileImageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
        {
            @Override
            public boolean onPreDraw()
            {
                profileImageView.getViewTreeObserver().removeOnPreDrawListener(this);

                //kv Using Math.max() to ensure that at least 1 dimension is positive
                //kv in case of some fucked up situation where the measured width and
                //kv height returns 0
                int widthProfileImageView = Math.max(profileImageView.getMeasuredWidth(), 1);
                int heightCardLayout = Math.max(profileImageView.getMeasuredHeight(), 1);

                //kv Somehow we can get into a situation where we in this PreDrawListener and there
                //kv are not give tens, which of course gives us a crash on mGiveTens.get(position)
                //kv If we find ourselves in that case, just show icon_photo_placement_lg
                if (mGiveTens.size() > 0)
                {
                    Picasso picasso = Picasso.with(Bakery.getInstance());
                    picasso.setIndicatorsEnabled(BuildConfig.DEBUG);
                    picasso.load(mGiveTens.get(position).getUserProfile().getProfilePic().getUrl())
                            .noFade()
                            .resize(widthProfileImageView, heightCardLayout)
                            .centerCrop()
                            .transform(new PicassoTransformationRounded(RADIUS, 0))
                            .into(profileImageView);
                }
                else
                {
                    profileImageView.setImageResource(R.drawable.icon_photo_placement_lg);
                }

                return true;
            }
        });

        TextView profilePicGenderCriteriaTextView = (TextView) cardLayout.findViewById(R.id.give_ten_profile_pic_textview_gender_criteria);
        TextView profilePicCityTextView = (TextView) cardLayout.findViewById(R.id.give_ten_profile_pic_textview_city);

        if (profile.getCriteriaGender().equals("m"))
        {
            profilePicGenderCriteriaTextView.setText(R.string.give_ten_text_gender_criteria_male);
        }
        else
        {
            profilePicGenderCriteriaTextView.setText(R.string.give_ten_text_gender_criteria_female);
        }

        String cityText = mContext.getResources().getString(R.string.give_ten_profile_pic_text_city_prefix)
                + " "
                + mGiveTens.get(position).getUserProfile().getCity()
                + ", "
                + mGiveTens.get(position).getUserProfile().getState();

        profilePicCityTextView.setText(cityText);

        container.addView(cardLayout);

        final RelativeLayout giveTenDetailsLayout = getDetailsLayout(cardLayout, giveTen);

        viewFiller.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Logger.d("view=" + view);

                boolean shouldCrossFade = !mListenerOnGiveTakeClick.onGiveTenClick(position - 1, true);

                if (mIsCrossFadeAnimationRunning == false && position > 0 && shouldCrossFade)
                {
                    crossfadeViews(profilePicLayout, giveTenDetailsLayout);
                    ManagerAnalytics.sendEvent(ManagerAnalytics.EVENT_VISITED_GIVE_TEN_CARD, ManagerAnalytics.ST1_PAGEVIEW);
                }
            }
        });

        View.OnClickListener onClickListener = new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Logger.d("view=" + view);

                boolean shouldCrossFade = !mListenerOnGiveTakeClick.onGiveTenClick(position, false);

                if (mIsCrossFadeAnimationRunning == false && shouldCrossFade)
                {
                    crossfadeViews(giveTenDetailsLayout, profilePicLayout);
                    ManagerAnalytics.sendEvent(ManagerAnalytics.EVENT_VISITED_GIVE_TEN_CARD, ManagerAnalytics.ST1_PAGEVIEW);
                }
            }
        };

        cardLayout.setOnClickListener(onClickListener);

        ScrollView giveTenCardDetailScrollContainer = (ScrollView) cardLayout.findViewById(R.id.give_ten_card_detail_scroll_container);

        if (giveTenCardDetailScrollContainer != null)
        {
            LinearLayout giveTenDetailsFieldLayout = (LinearLayout) giveTenCardDetailScrollContainer.findViewById(R.id.give_ten_detail_fields_layout);

            giveTenDetailsFieldLayout.setTag(profile);
            giveTenDetailsFieldLayout.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view)
                {
                    Logger.d("view=" + view);

                    boolean shouldCrossFade = !mListenerOnGiveTakeClick.onGiveTenClick(position, false);

                    if (mIsCrossFadeAnimationRunning == false && shouldCrossFade)
                    {
                        crossfadeViews(profilePicLayout, giveTenDetailsLayout);
                        ManagerAnalytics.sendEvent(ManagerAnalytics.EVENT_VISITED_GIVE_TEN_CARD, ManagerAnalytics.ST1_PAGEVIEW);
                    }
                }
            });
        }
        return cardLayout;
    }

    private void crossfadeViews(final View view1, final View view2)
    {
        final View visibleView, invisibleView;

        if (view1.getVisibility() == View.VISIBLE)
        {
            visibleView = view1;
            invisibleView = view2;
        }
        else
        {
            visibleView = view2;
            invisibleView = view1;
        }

        mIsCrossFadeAnimationRunning = true;
        invisibleView.setAlpha(0.0f);
        invisibleView.setVisibility(View.VISIBLE);

        invisibleView.animate()
                .alpha(1.0f)
                .setDuration(ANIMATION_DURATION)
                .setListener(new AnimatorListenerAdapter()
                {
                    @Override
                    public void onAnimationEnd(Animator animation)
                    {
                        mIsCrossFadeAnimationRunning = false;
                    }
                });

        visibleView.animate()
                .alpha(0.0f)
                .setDuration(ANIMATION_DURATION)
                .setListener(new AnimatorListenerAdapter()
                {
                    @Override
                    public void onAnimationEnd(Animator animation)
                    {
                        visibleView.setVisibility(View.GONE);
                        mIsCrossFadeAnimationRunning = false;
                    }
                });

    }

    public void crossFadeViews(View view)
    {
        final RelativeLayout giveTenDetailLayout = (RelativeLayout) view.findViewById(R.id.give_ten_detail_layout);
        final RelativeLayout profilePicLayout = (RelativeLayout) view.findViewById(R.id.give_ten_profile_pic_layout);
        crossfadeViews(profilePicLayout, giveTenDetailLayout);
    }

    private RelativeLayout getDetailsLayout(View parent, GiveTen giveTen)
    {
        RelativeLayout giveTenDetailsLayout = (RelativeLayout) parent.findViewById(R.id.give_ten_detail_layout);

        UserProfile profile = giveTen.getUserProfile();

        TextView genderCriteriaTextView = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_gender_criteria_textview);

        if (profile.getCriteriaGender().equals("m"))
        {
            genderCriteriaTextView.setText(R.string.give_ten_text_gender_criteria_male);
        }
        else
        {
            genderCriteriaTextView.setText(R.string.give_ten_text_gender_criteria_female);
        }

        TextView cityTextView = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_city_textview);
        cityTextView.setText(profile.getCity() + ", " + giveTen.getUserProfile().getState());

        TextView ageTextView = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_age_textview);
        ageTextView.setText(mContext.getResources().getString(R.string.give_ten_text_age)
                + " "
                + DateUtils.getAgeFromBirthday(profile.getBirthday()));

        TextView heightTextView = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_height_textview);
        heightTextView.setText(mContext.getResources().getString(R.string.give_ten_text_height)
                + " "
                + profile.getHeightFeet()
                + "'"
                + profile.getHeightInches());

        TextView religionTextView = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_religion_textview);
        religionTextView.setText((mContext.getResources().getStringArray(R.array.religion)[Religion.getIndex(profile.getReligionApiParam())]));

        TextView educationTextView0 = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_education_1_textview);
        TextView educationTextView1 = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_education_2_textview);

        List<String> education = profile.getEducation();
        List<Degree> degree = profile.getListDegrees();

        if (education.size() > 0)
        {
            if (degree.size() > 0)
            {
                educationTextView0.setText(education.get(0) + "/" + degree.get(0).toString().toLowerCase());
            }
            else
            {
                educationTextView0.setText(education.get(0));
            }

            if (education.size() > 1)
            {
                if (degree.size() > 1)
                {
                    educationTextView1.setText(education.get(1) + "/" + degree.get(1).toString().toLowerCase());
                }
                else
                {
                    educationTextView1.setText(education.get(1));
                }

                educationTextView1.setVisibility(View.VISIBLE);
            }
        }

        TextView occupation = (TextView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_occupation_textview);
        occupation.setText(profile.getOccupation());

        final List<ImageView> giveTenDetailPics = new ArrayList<ImageView>();
        giveTenDetailPics.add((ImageView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_pic_1));
        giveTenDetailPics.add((ImageView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_pic_2));
        giveTenDetailPics.add((ImageView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_pic_3));
        giveTenDetailPics.add((ImageView) giveTenDetailsLayout.findViewById(R.id.give_ten_detail_pic_4));

        //kv Calculate length of side for photos
        float widthPhotoLayout = ViewUtils.getScreenWidth() -
                2 * mContext.getResources().getDimension(R.dimen.give_ten_layout_margin_side) -
                2 * mContext.getResources().getDimension(R.dimen.give_ten_detail_margin_side) -
                6 * mContext.getResources().getDimension(R.dimen.give_ten_photo_margin_side);

        mSquarePhotoSideLength = (int) (widthPhotoLayout / 4);

        List<Photo> detailPhotos = profile.getPhotos();
        for (int i = 0; i < detailPhotos.size(); i++)
        {
            final ImageView imageView = giveTenDetailPics.get(i);
            final Photo photo = detailPhotos.get(i);

            final String url = photo.getUrlThumbnail();
            Logger.d("about to display " + url + ", length=" + mSquarePhotoSideLength);

            Picasso.with(mContext)
                    .load(url)
                    .noFade()
                    .resize(mSquarePhotoSideLength, mSquarePhotoSideLength)
                    .placeholder(R.drawable.icon_photo_placement_s)
                    .into(imageView, new Callback()
                    {
                        @Override
                        public void onSuccess()
                        {
                            //Logger.e("success on " + url);
                        }

                        @Override
                        public void onError()
                        {
                            Logger.e("error");
                        }
                    });
        }

        return giveTenDetailsLayout;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object)
    {
        container.removeView((View) object);
    }
}
Respectable answered 23/3, 2015 at 20:26 Comment(9)
can you please post your pageradapter classClingfish
@Hell entire PagerAdapter class addedRespectable
you don't have the getItem method in your pageradapterClingfish
check out this tutorial it's very much descriptive wptrafficanalyzer.in/blog/…Clingfish
how are you showing more than one page at time ?Shiver
@Hell PagerAdapters don't have getItem(); you must be thinking about FragmentPagerAdapters.Respectable
@Shiver You can show more than one page at a time by setting a negative margin on ViewPager.setPageMargin()Respectable
@karim are you getting the current page in repeated order!Clingfish
@Hell No nothing is getting reported.Respectable
R
2

You could intercept touch events and get coordinates from that event.

    if(event.getRawX() < margin && canGoLeft){
goLeft();
}
else if(event.getRawX() > screenWidth - margin && canGoRight) {
goRight();
}
else { 
  // We are not interested in this event, pass it down the food chain
}
Ragamuffin answered 15/4, 2015 at 16:32 Comment(0)
V
2

It's not a bug.. you have to use different method for it.

Just try the method above the instantiateItem ,

@Override
public void setPrimaryItem(View container, final int position, Object object)
{}

Here position return correct which you have required..

Vanburen answered 14/4, 2015 at 14:7 Comment(1)
Thanks guys, but I don't understand. What am I supposed to do in setPrimaryItem()?Respectable
R
2

You could intercept touch events and get coordinates from that event.

    if(event.getRawX() < margin && canGoLeft){
goLeft();
}
else if(event.getRawX() > screenWidth - margin && canGoRight) {
goRight();
}
else { 
  // We are not interested in this event, pass it down the food chain
}
Ragamuffin answered 15/4, 2015 at 16:32 Comment(0)
G
0

I think that you have to do is implement ViewPagerAdapter that extends of PagerAdapter. Basically, in your activity you set the images for the adapter and then set the ViewPagerAdapter to the ViewPager class

in your class activity

ViewPagerAdapter.Images = getImages();
ViewPager.setAdapter(ViewPagerAdapter);
ViewPager.setCurrentItem(getImages().indexOf(selectedImage))

You need to create a ViewPagerAdapter class that extends of PageAdapter

Finally add the viewpager control to the layout

   <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

Here you can see an example done using framgents http://developer.android.com/training/animation/screen-slide.html

Grazynagreabe answered 23/3, 2015 at 20:59 Comment(1)
Thanks for your answer Salim. I have implemented a custom PagerAdapter. The instantiateItem() method in my post is from my custom PagerAdapter.Respectable
J
0

You must add padding to viewpager for boundaries, and I think position is correct work. Can you try?

viewPager.setPadding(40, 0, 40, 0); (left,top,right,bottom)

viewpager.setClipToPadding(false);
Jidda answered 14/4, 2015 at 7:10 Comment(1)
Thanks Mustafa, but I can't set padding on the ViewPager or else I won't the look in the screenshot. The Views to the left and right of the center view must go to the edges of the screen.Respectable

© 2022 - 2024 — McMap. All rights reserved.