Android PagerAdapter не сообщает правильную позицию, если нажать предыдущий элемент

У меня есть ViewPager w/negative margin, чтобы получить такой эффект: enter image description here

Теперь, я хочу, чтобы это произошло, когда я нажимаю на представление слева или справа от текущего представления. Он должен выбрать этот вид и вызвать setCurrentItem() в ViewPager. Это отлично работает с видом справа от текущего элемента, но не с видом слева от текущего элемента. Когда я нажимаю на это представление, позиция, о которой мне сообщают, относится к текущему виду.

Вот какой код, если это поможет. Это от PagerAdapter.instantiateItem(), где я запускаю 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
            }
        });
    }

Целый класс PagerAdapter для всех, кто заинтересован:

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);
    }
}

Ответ 1

Вы можете перехватывать события касания и получать координаты от этого события.

    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
}

Ответ 2

Это не ошибка... вам нужно использовать для этого другой метод.

Просто попробуйте метод выше instantiateItem,

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

Здесь позиция возвращает правильную, которая вам нужна.

Ответ 3

Я думаю, что вам нужно реализовать ViewPagerAdapter, который расширяет PagerAdapter. В основном, в вашей деятельности вы устанавливаете изображения для адаптера, а затем устанавливаете ViewPagerAdapter классу ViewPager

в вашем классе.

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

Вам необходимо создать класс ViewPagerAdapter, который расширяет страницу PageAdapter

Наконец добавьте элемент управления viewpager в макет

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

Здесь вы можете увидеть пример, выполненный с использованием фреймов http://developer.android.com/training/animation/screen-slide.html

Ответ 4

Вы должны добавить дополнение к viewpager для границ, и я думаю, что позиция - это правильная работа. Вы можете попробовать?

viewPager.setPadding(40, 0, 40, 0); (слева, сверху, справа, внизу)

viewpager.setClipToPadding(false);