I'm trying to create an HorizontalScrollView with a RecyclerView, I have my adapter with FirebaseAdapter with my onCreateViewHolder, onDataChanged and its onBindViewHolder, what I'd like to add on my RecyclerView is something like this Image, something like, user only will see 3 items, and the centered zoomed/bigger, someone told me that I have to override getItemViewType, but I do not know how to, could you guide to how to do it?
To make it act like an HorizontalScrollView I've added a CustomLinearLayout like this :
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); rv.setLayoutManager(layoutManager); What I'd like it to show is like this (each blank rectangle is an item) :
FOR THOSE WHO DON'T UNDERSTAND
I allready have a RecyclerView which acts like HorizontalScrollView BUT I'm not able to make that customizable, to show it like the image from above.
4 Answers
Answers 1
Actually this is a popular thing to implement, so the solution already exists on GitHub - https://github.com/yarolegovich/DiscreteScrollView. It's highly customizable, so you can adjust it for your needs and metrics. Here is an example from that lib:
Answers 2
i have faced something like this but i fixed it from changing it from recylerview to ViewPager it is more smoother and better in performance first the xml layout you will work with the margins and padding , it consists of 4 classes with are shadow transform for the animation you want ,cardFragmentPagerAdapter for the pager adapter , interface cardAdapter for the elevations of the cards and a cardFragment for the layout appearence
<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" /> then you will set the margin of the viewpager
int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10 * 2, getResources().getDisplayMetrics()); viewPager.setPageMargin(-margin); viewPager.setClipChildren(false); then you will set the adapter to the viewpager and its shadow transform which is responsible for the animation
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); your CardFragmentPagerAdapter code is
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; } }
the cardAdapter is an interface for the elevation
import android.support.v7.widget.CardView; public interface CardAdapter { int MAX_ELEVATION_FACTOR = 8; float getBaseElevation(); CardView getCardViewAt(int position); int getCount(); } your shadow transform class is
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) { } } the cardFragment for the layout
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;} Answers 3
Please Try to see if this helps.
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(); } } }
Answers 4
Set a linearLayoutManager to get your recyclerView to work like horizontalScrollView.
Example here


0 comments:
Post a Comment