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