【问题标题】:Custom HorizontalScrollView adapter RecyclerView自定义 Horizo​​ntalScrollView 适配器 RecyclerView
【发布时间】:2018-06-11 01:38:17
【问题描述】:

我正在尝试使用RecyclerView 创建一个HorizontalScrollView,我的适配器带有FirebaseAdapter 和我的onCreateViewHolderonDataChanged 及其onBindViewHolder,我想补充一下我的RecyclerView 是这样的Image,类似于,用户只会看到 3 个项目,并且居中缩放/更大,有人告诉我必须覆盖 getItemViewType,但我不知道如何,可以你指导怎么做?

为了让它表现得像 HorizontalScrollView,我添加了一个 CustomLinearLayout,如下所示:

LinearLayoutManager layoutManager = 
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
rv.setLayoutManager(layoutManager);

我希望它显示的是这样的(每个空白矩形都是一个项目):

对于那些不懂的人

我已经有一个RecyclerView,它的行为类似于HorizontalScrollView 但是我无法进行自定义,以便像上面的图片一样显示它。

【问题讨论】:

  • 我理解正确吗?您想在屏幕上同时显示 3 个项目(A、B、C),其中 B 大于 A 和 C。如果我们向左滑动,屏幕将显示 B、C、D -- 其中 C 为更大?
  • @Gary99 没错!如有必要,我会上传一段视频,说明我想要获得什么。
  • 贴出栏目布局的xml

标签: android android-layout android-recyclerview horizontal-scrolling


【解决方案1】:

实际上这是一个流行的实现方式,因此该解决方案已经存在于 GitHub 上 - https://github.com/yarolegovich/DiscreteScrollView。它是高度可定制的,因此您可以根据自己的需求和指标进行调整。这是该库中的一个示例:

【讨论】:

    【解决方案2】:

    我遇到过类似的情况,但我将其从 recylerview 更改为 ViewPager 进行了修复,它更流畅,性能更好 首先,您将使用边距和填充的 xml 布局,它由 4 个类组成,其中包括用于所需动画的阴影变换、用于寻呼机适配器的 cardFragmentPagerAdapter、用于卡片高度的接口 cardAdapter 和用于布局外观的 cardFragment

    <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="130dp"
            android:layout_alignParentBottom="true"
            android:clipToPadding="false"
            android:overScrollMode="never"
            android:paddingEnd="80dp"
            android:paddingLeft="80dp"
            android:paddingRight="80dp"
            android:paddingStart="80dp" />
    

    然后你将设置viewpager的边距

    int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10 * 2,
                getResources().getDisplayMetrics());
    
        viewPager.setPageMargin(-margin);
        viewPager.setClipChildren(false);
    

    然后您将适配器设置为 viewpager 及其负责动画的阴影变换

    pagerAdapter = new CardFragmentPagerAdapter(getSupportFragmentManager(),
                                        dpToPixels(2, JobMapActivity.this),
                                        titlesCard, catIconCard, catNameCard, startDateCard, startTimeCard);
                                viewPager.setAdapter(pagerAdapter);
                                viewPager.setOffscreenPageLimit(3);
                                ShadowTransformer fragmentCardShadowTransformer = new ShadowTransformer(viewPager, pagerAdapter);
                                fragmentCardShadowTransformer.enableScaling(true);
                                viewPager.setPageTransformer(false, fragmentCardShadowTransformer);
    

    您的 CardFragmentPagerAdapter 代码是

    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.support.v7.widget.CardView;
    import android.util.SparseArray;
    import android.view.ViewGroup;
    
    import java.util.ArrayList;
    import java.util.List;
    public class CardFragmentPagerAdapter extends FragmentStatePagerAdapter implements CardAdapter {
    
    private List<CardFragment> fragments;
    SparseArray<Fragment> registeredFragments = new SparseArray<>();
    private float baseElevation;
    ArrayList<String> titles, icons, names, dates, times;
    
    public CardFragmentPagerAdapter(FragmentManager fm, float baseElevation,
                                    ArrayList<String> title, ArrayList<String> icon,
                                    ArrayList<String> name, ArrayList<String> startDate,
                                    ArrayList<String> startTime) {
        super(fm);
        fragments = new ArrayList<>();
        this.baseElevation = baseElevation;
        titles = title;
        icons = icon;
        names = name;
        dates = startDate;
        times = startTime;
        for (int i = 0; i < titles.size(); i++) {
            addCardFragment(new CardFragment());
        }
    }
    
    @Override
    public float getBaseElevation() {
        return baseElevation;
    }
    
    @Override
    public CardView getCardViewAt(int position) {
        return fragments.get(position).getCardView();
    }
    
    @Override
    public int getCount() {
        return fragments.size();
    }
    
    @Override
    public Fragment getItem(int position) {
        return CardFragment.getInstance(position, titles.get(position),
                icons.get(position), names.get(position), dates.get(position), times.get(position));
    }
    
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
        registeredFragments.remove(position);
    }
    
    public void addCardFragment(CardFragment fragment) {
        fragments.add(fragment);
    }
    
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object fragment = super.instantiateItem(container, position);
        Fragment fragment2 = (Fragment) super.instantiateItem(container, position);
        fragments.set(position, (CardFragment) fragment);
        registeredFragments.put(position, fragment2);
        return fragment;
    }
    
    public String getRegisteredFragment(int position) {
        return fragments.get(position).getTitle();
    }
    
    
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
    

    }

    cardAdapter 是海拔的接口

        import android.support.v7.widget.CardView;
    
    public interface CardAdapter {
    
        int MAX_ELEVATION_FACTOR = 8;
    
        float getBaseElevation();
    
        CardView getCardViewAt(int position);
    
        int getCount();
    }
    

    你的阴影变换类是

      import android.support.v4.view.ViewPager;
    import android.support.v7.widget.CardView;
    import android.view.View;
    
    import com.foksart.greatskillsfixers.adapters.CardAdapter;
    
    public class ShadowTransformer implements ViewPager.OnPageChangeListener, ViewPager.PageTransformer {
    
        private ViewPager viewPager;
        private CardAdapter cardAdapter;
        private float lastOffset;
        private boolean scalingEnabled;
    
        public ShadowTransformer(ViewPager viewPager, CardAdapter adapter) {
            this.viewPager = viewPager;
            viewPager.addOnPageChangeListener(this);
            cardAdapter = adapter;
        }
    
        public void enableScaling(boolean enable) {
            if (scalingEnabled && !enable) {
                // shrink main card
                CardView currentCard = cardAdapter.getCardViewAt(viewPager.getCurrentItem());
                if (currentCard != null) {
                    currentCard.animate().scaleY(.9f);
    //                currentCard.animate().scaleX(.9f);
                }
            }else if(!scalingEnabled && enable){
                // grow main card
                CardView currentCard = cardAdapter.getCardViewAt(viewPager.getCurrentItem());
                if (currentCard != null) {
                    //enlarge the current item
                    currentCard.animate().scaleY(1.3f);
    //                currentCard.animate().scaleX(1.3f);
                }
            }
            scalingEnabled = enable;
        }
    
        @Override
        public void transformPage(View page, float position) {
    
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            int realCurrentPosition;
            int nextPosition;
            float baseElevation = cardAdapter.getBaseElevation();
            float realOffset;
            boolean goingLeft = lastOffset > positionOffset;
    
            // If we're going backwards, onPageScrolled receives the last position
            // instead of the current one
            if (goingLeft) {
                realCurrentPosition = position + 1;
                nextPosition = position;
                realOffset = 1 - positionOffset;
            } else {
                nextPosition = position + 1;
                realCurrentPosition = position;
                realOffset = positionOffset;
            }
    
            // Avoid crash on overscroll
            if (nextPosition > cardAdapter.getCount() - 1
                    || realCurrentPosition > cardAdapter.getCount() - 1) {
                return;
            }
    
            CardView currentCard = cardAdapter.getCardViewAt(realCurrentPosition);
    
            // This might be null if a fragment is being used
            // and the views weren't created yet
            if (currentCard != null) {
                if (scalingEnabled) {
                    currentCard.setScaleX((float) (1 + 0.1 * (1 - realOffset)));
                    currentCard.setScaleY((float) (1 + 0.1 * (1 - realOffset)));
                }
                currentCard.setCardElevation((baseElevation + baseElevation
                        * (CardAdapter.MAX_ELEVATION_FACTOR - 1) * (1 - realOffset)));
            }
    
            CardView nextCard = cardAdapter.getCardViewAt(nextPosition);
    
            // We might be scrolling fast enough so that the next (or previous) card
            // was already destroyed or a fragment might not have been created yet
            if (nextCard != null) {
                if (scalingEnabled) {
                    nextCard.setScaleX((float) (1 + 0.1 * (realOffset)));
                    nextCard.setScaleY((float) (1 + 0.1 * (realOffset)));
                }
                nextCard.setCardElevation((baseElevation + baseElevation
                        * (CardAdapter.MAX_ELEVATION_FACTOR - 1) * (realOffset)));
            }
    
            lastOffset = positionOffset;
        }
    
        @Override
        public void onPageSelected(int position) {
    
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
    
        }
    }
    

    用于布局的 cardFragment

        import android.graphics.Color;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v7.widget.CardView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.bumptech.glide.Glide;
    import com.foksart.greatskillsfixers.ActivityClasses.JobMapActivity;
    import com.foksart.greatskillsfixers.R;
    
    
    public class CardFragment extends Fragment {
    
        private CardView cardView;
        int position;
        String title, icon, name, date, time;
    
        public static Fragment getInstance(int position, String title,
                                           String icon, String name,
                                           String date, String time) {
            CardFragment f = new CardFragment();
            Bundle args = new Bundle();
            args.putInt("position", position);
            args.putString("title", title);
            args.putString("icon", icon);
            args.putString("name", name);
            args.putString("date", date);
            args.putString("time", time);
    
            f.setArguments(args);
            return f;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.card_map_item, container, false);
            cardView = view.findViewById(R.id.cardView);
            cardView.setMaxCardElevation(cardView.getCardElevation() * CardAdapter.MAX_ELEVATION_FACTOR);
            TextView jobTitle = view.findViewById(R.id.jobTitle);
            jobTitle.setText(title);
    
            ImageView catIcon = view.findViewById(R.id.catIcon);
            Glide.with(getActivity()).load(icon).into(catIcon);
            catIcon.setColorFilter(Color.parseColor("#969798"));
    
            TextView catName = view.findViewById(R.id.catName);
            catName.setText(name);
    
            TextView Date = view.findViewById(R.id.Date);
            Date.setText(date);
    
            TextView Time = view.findViewById(R.id.Time);
            Time.setText(time);
    
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ((JobMapActivity)getActivity()).viewPagerClick(position);
                }
            });
    
            return view;
        }
    
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            position = getArguments().getInt("position");
            title = getArguments().getString("title");
            icon = getArguments().getString("icon");
            name = getArguments().getString("name");
            date = getArguments().getString("date");
            time = getArguments().getString("time");
        }
    
        public CardView getCardView() {
            return cardView;
        }
    
    
        public String getTitle(){return title;}
    

    【讨论】:

    • 你能不能做一个 gif 或者什么我想在复制你的代码后首先看到输出,谢谢。另外,我正在寻找 RecyclerView 而不是 ViewPager
    • 我知道你正在寻找 recyclerview ,我首先从 recycler view 开始,然后我改为 viewpager @Stuart2041
    • 问题是 Firebase 适配器不接受 ViewPager,但感谢它可能对其他人有用:)
    【解决方案3】:

    请尝试看看这是否有帮助。

    public class MainActivity extends AppCompatActivity {
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        List<String>texts = new ArrayList<>();
        texts.add("test 1");
        texts.add("test 2");
        texts.add("test 3");
        texts.add("test 4");
        texts.add("test 5");
    
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    
        RecyclerView myList = (RecyclerView) findViewById(R.id.RV);
        myList.setLayoutManager(layoutManager);
        myList.setAdapter(new TestAdapter(texts));
    
    }
    
    
     class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> {
    
        private List<String> TextsList;
    
        public class MyViewHolder extends RecyclerView.ViewHolder {
             public TextView title;
    
             public MyViewHolder(View view) {
                 super(view);
                 title = (TextView) view.findViewById(R.id.title);
             }
         }
    
    
         public class MyBigViewHolder extends RecyclerView.ViewHolder {
             public TextView title;
    
             public MyBigViewHolder(View view) {
                 super(view);
                 title = (TextView) view.findViewById(R.id.title);
             }
         }
    
    
        public TestAdapter(List<String> textsList) {
            this.TextsList = textsList;
        }
    
         @Override
         public int getItemViewType(int position) {
             // Just as an example, return 0 or 2 depending on position
             // Note that unlike in ListView adapters, types don't have to be contiguous
             return position % 2 * 3;
         }
    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = null;
                if(viewType == 0) {
                    itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_row_2, parent, false);
                }else{
                    itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_row, parent, false);
                }
    
            return new MyViewHolder(itemView);
        }
    
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            String text = TextsList.get(position);
            holder.title.setText(text);
        }
    
        @Override
        public int getItemCount() {
            return TextsList.size();
        }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      相关资源
      最近更新 更多