如果单击上一项,Android PagerAdapter 不会报告正确的位置

标签 android android-pageradapter

我有一个带负边距的 ViewPager 设置来获得这样的效果: enter image description here

现在,我想要发生的是,当我单击当前 View 左侧或右侧的 View 时。它应该选择该 View 并调用 ViewPager 上的 setCurrentItem()。这适用于当前项目右侧的 View ,但不适用于当前项目左侧的 View 。当我单击该 View 时,向我报告的位置是当前 View 的位置。

如果有帮助,这里有一些代码。这是来 self 在 onClick() 上触发的 PagerAdapter.instantiateItem():

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

最佳答案

您可以拦截触摸事件并从该事件中获取坐标。

    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
}

关于如果单击上一项,Android PagerAdapter 不会报告正确的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29219706/

相关文章:

Android 仪表板图标大小

android - 在 RecyclerView/ListView onScroll 上隐藏 ActionBar

android - ViewPager 偏移光标位置

android - 应该如何在 PagerAdapter 中使用 getApplication 方法

android - 无法过滤 PagedList?

android - 应用程序长时间在后台丢失数据

android - Android/iOS 上的蓝牙游戏

android - Jetpack Compose - TextField 在底部剪切文本

android - 实例化 PagerAdapter Android

android - Imageview 和 PagerAdapter