I have been searching and found some close questions and answer but none of them works.
I'm using CoordinatorLayout for a list RecyclerView with AppBarLayout and ToolBar.
My Goal:
The ideia is very simple, when you roll the view first the AppBar Collapse in the Toolbar and after that the RecyclerView start to scroll.
My Hierarchy:
My Fragment RecyclerView(vertical) has a Adapter-A with a new layout, and this adapter call a second adapter-B for the RecyclerView(horizontal).
So I Have a struct like this:
(is not a code, just to show how works)
Fragment AppBarLayout{..}
Fragment Recycler View (Vertical) {
Adapter-A Text;
Adapter-A Recycler View (Horizontal){
Adapter-B Img;
Adapter-B Text;
}
}
What is the problem:
If I click in the RecyclerView(Vertical) or Adapter-A Img it works fine.
But If I click in Adapter B content(Img and Text) it scroll both Recycler Views but not the AppBar.
What I'm doing:
I use
app:layout_behavior="#string/appbar_scrolling_view_behavior"
recyclerList.setHasFixedSize(true)
recyclerList.setNestedScrollingEnabled(true);
in both Recycler Views.
app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlways"
in the CollapsingToolbarLayout
I try to make this in java code:
recyclerList.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// If AppBar is fully expanded, revert the scroll.
if (!shouldScroll) {
recyclerList.scrollToPosition(0);
//Here I should make the AppBar Scroll, but AppBarLayout.scrollTo(dx, dy) don't work.
}
}
});
mainHomeAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
shouldScroll = verticalOffset != 0;
}
});
My code:
mainHome.xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/main_home_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:id="#+id/main_home_app_bar_layout"
android:layout_width="match_parent"
android:layout_height="192dp"
android:background="#drawable/gradient_bg">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlways">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
mainHome.java
#Override
protected void assignViews() {
mainHomeList = (RecyclerView) findViewById(R.id.main_home_list);
mainHomeAppBarLayout = (AppBarLayout) findViewById(R.id.main_home_app_bar_layout);
}
#Override
protected void prepareViews() {
mainHomeList.setHasFixedSize(true);
mainHomeList.setNestedScrollingEnabled(true);
linearLayoutManager = new LinearLayoutManager(getApplicationContext());
mainHomeList.setLayoutManager(linearLayoutManager);
initAdapterIfNecessary();
if (mainHomeList.getAdapter() == null)
mainHomeList.setAdapter(adapter);
}
adapter-A.java
public class MainHomeModulesAdapter extends RecyclerView.Adapter<MainHomeModulesAdapter.GroupViewHolder> {
private OnListItemClickedListener onListItemClickedListener = null;
private OnListItemClickedTwoListener onListItemClickedTwoListener = null;
private ArrayList<JSONMainModule> mainModules = new ArrayList<>();
#Override
public MainHomeModulesAdapter.GroupViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
View itemView = LayoutInflater.from(context).inflate(R.layout.a_main_home_module_item, parent, false);
return (new MainHomeModulesAdapter.GroupViewHolder(itemView));
}
#Override
public void onBindViewHolder(MainHomeModulesAdapter.GroupViewHolder holder, int position) {
//Place where put layout information
holder.mainHomeModuleList.setLayoutManager(new GridLayoutManager(context, Utils.calcGridSpaceCount(context, 2))); //For two elements
holder.mainHomeModuleList.setAdapter(holder.mainHomeContentAdapter);
holder.mainHomeContentAdapter.updateListContent(mainModules.get(position).getModuleContent(), mainModules.get(position).getModule());
}
#Override
public int getItemCount() {
return mainModules.size();
}
public void setOnListItemClickedListener(OnListItemClickedListener onListItemClickedListener) {
this.onListItemClickedListener = onListItemClickedListener;
}
public void setOnListItemClickedTwoListener(OnListItemClickedTwoListener onListItemClickedTwoListener){
this.onListItemClickedTwoListener = onListItemClickedTwoListener;
}
public void updateListContent(ArrayList<JSONMainModule> mainModules) {
this.mainModules = mainModules;
notifyDataSetChanged();
}
public JSONMainModule getListContent(int pos) {
return mainModules.get(pos);
}
class GroupViewHolder extends ParentViewHolder {
TextView mainHomeModuleText;
Button mainHomeModuleBtn;
RecyclerView mainHomeModuleList;
MainHomeContentAdapter mainHomeContentAdapter; //Adapter-B
private GroupViewHolder(View itemView) {
super(itemView);
mainHomeModuleText = (TextView) itemView.findViewById(R.id.main_home_module_title);
mainHomeModuleBtn = (Button) itemView.findViewById(R.id.main_home_module_btn);
mainHomeModuleBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ATUtils.isDoubleClick()) return;
onListItemClickedListener.onClicked(getAdapterPosition());
}
});
//Child - Main Contents
mainHomeModuleList = (RecyclerView) itemView.findViewById(R.id.main_home_module_list);
mainHomeModuleList.setHasFixedSize(true);
mainHomeModuleList.setNestedScrollingEnabled(true);
mainHomeContentAdapter = new MainHomeContentAdapter();
mainHomeContentAdapter.setOnListItemClickedListener(new OnListItemClickedListener() {
#Override
public void onClicked(int pos) {
onListItemClickedTwoListener.onClicked(pos, getAdapterPosition());
}
});
}
}
}
Found a Solution.
When create the parent Vertical ListView set setNestedScrollingEnabled as true.
And when create the child Horizontal ListView set setNestedScrollingEnabled as false.
Related
Sometimes RecyclerView shows empty spaces at bottom if the screen is large or it has fewer items to cover the screen. Also sometimes it shows some items partially if it has more items. What I want is:
RecyclerView will cover the full available space with the given number
of rows. It will always fill the screen, no matter what is the size of
the screen.
How can I do that?
use match_parent for both width and height.
I'm posting my solution now for any future questioner. Here, by the word RESPONSIVE, I want the Items to take the available screen-space equally. For example, if we want 4 rows initially, the 4 rows will cover up the screen fully; that means, no item will be visible partially when the RecyclerView appears on the screen for the first time. And this will only work if the RecyclerView has fixed height irrespective of its Children, means, don't give WRAP_CONTENT to RecyclerView layout_height, give anything else like MATCH_PARENT or Constrained height.
Step1: You need to pass a parameter rows to the Adapter. You also need to pass the RecyclerView to the Adapter.
Step2: We need to keep a FLAG which will decide when to reveal the Child Items on the Screen. This FLAG will be FALSE initially, this will be TRUE when we finish calculating the available HEIGHT of RecyclerView on the screen. When we get the height of RecyclerView, we divide it by rows and get the height of each row. So we need to put a OnGlobalLayoutListener on the RecyclerView.
Here is a sample code.
RecyclerView layout will be like:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/recycler_view"
tools:listitem="#layout/item"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Item layout will be like:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp">
<TextView
android:padding="15dp"
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:enabled="true"
android:focusable="true"
android:longClickable="true"
android:textIsSelectable="true" />
</androidx.cardview.widget.CardView>
Adapter will be like:
public class ResponsiveItemListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener
{
public static final int NUMBER_OF_ROWS_AUTO = -1;
Context context;
LayoutInflater layoutInflater;
RecyclerViewItemClickListeners listener;
List<Item> items;
RecyclerView recyclerView;
int numberOfRows;
int rowHeightInPx = 0;
boolean itemHeightCalculationCompleted = false;
public ResponsiveItemListAdapter(Context context, List<Item> items, RecyclerViewItemClickListeners listener, RecyclerView rv, int rows)
{
super();
this.context = context;
this.items = items;
this.listener = listener;
this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.recyclerView = rv;
this.numberOfRows = rows;
if (this.numberOfRows > 0)
{
this.recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
if (recyclerView.getMeasuredHeight() > 0)
{
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
setRowHeightInPx(recyclerView.getMeasuredHeight() / numberOfRows);
itemHeightCalculationCompleted = true;
notifyDataSetChanged();
}
}
});
} else
{
itemHeightCalculationCompleted = true;
}
}
public int getRowHeightInPx()
{
return rowHeightInPx;
}
public void setRowHeightInPx(int rowHeightInPx)
{
this.rowHeightInPx = rowHeightInPx;
}
#Override
public int getItemCount()
{
if (this.items != null && this.itemHeightCalculationCompleted)
return this.items.size();
else
return 0;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
RecyclerView.ViewHolder vh;
View view = this.layoutInflater.inflate(R.layout.item, parent, false);
if (getRowHeightInPx() > 0)
{
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
layoutParams.height = getRowHeightInPx();
layoutParams.width = MATCH_PARENT;
view.setLayoutParams(layoutParams);
}
vh = new GeneralViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
Item page = items.get(position);
CardView view = ((CardView) ((GeneralViewHolder) holder).getView());
((GeneralViewHolder) holder).getTitle().setText(page.getTitle());
((GeneralViewHolder) holder).getView().setOnClickListener(this);
((GeneralViewHolder) holder).getView().setTag(position);
}
#Override
public void onViewRecycled(RecyclerView.ViewHolder holder)
{
super.onViewRecycled(holder);
}
#Override
public void onClick(View v)
{
int position = (int) v.getTag();
this.listener.onRecyclerViewItemClick(this.items, position);
}
public class GeneralViewHolder extends RecyclerView.ViewHolder
{
View view;
TextView title;
public GeneralViewHolder(View itemView)
{
super(itemView);
view = itemView;
title = itemView.findViewById(R.id.title);
}
public View getView()
{
return view;
}
public TextView getTitle()
{
return title;
}
}
public interface RecyclerViewItemClickListeners
{
void onRecyclerViewItemClick(List<Item> items, int position);
}
}
Set the adapter like this:
public class MainActivity extends AppCompatActivity implements ResponsiveItemListAdapter.RecyclerViewItemClickListeners
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Item> items = new ArrayList<>();
items.add(new Item("One"));
items.add(new Item("Two"));
items.add(new Item("Three"));
items.add(new Item("Four"));
items.add(new Item("Five"));
items.add(new Item("Six"));
items.add(new Item("Seven"));
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new ResponsiveItemListAdapter(this, items, this, recyclerView, 3));
}
#Override
public void onRecyclerViewItemClick(List<Item> items, int position)
{
Toast.makeText(this, items.get(position).getTitle(), Toast.LENGTH_LONG).show();
}
}
And here is the output:
I would like to enable fling/fast scrolling on the recycler view. What I mean is that if user performs fling motion, the view continues scrolling and starts decelerating (I guess that's called fast scrolling).
I have a RecyclerView in a ScrollView
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scroll">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/items"/>
</ScrollView>
I set layout manager to Linear
RecyclerView itemsView = findViewById(R.id.items);
stocksView.setLayoutManager(new LinearLayoutManager(this));
I do have a custom adapter attached to the RecyclerView
public abstract class RecyclerAdapter<E>
extends RecyclerView.Adapter<ItemView>
{
private ItemTouchHelper touchHelper;
protected final List<E> items = new ArrayList<>();
protected RecyclerAdapter()
{
}
#Override
public void onBindViewHolder(#NonNull final ItemView holder, int position)
{
}
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView)
{
super.onAttachedToRecyclerView(recyclerView);
touchHelper = new ItemTouchHelper(new ItemTouchHelperCallback(this));
touchHelper.attachToRecyclerView(recyclerView);
}
#Override
public int getItemCount()
{
return items.size();
}
}
And my ItemTouchHelperCallback is
public class ItemTouchHelperCallback
extends ItemTouchHelper.Callback
{
ItemTouchHelperCallback(RecyclerAdapter adapter)
{
}
#Override
public boolean isItemViewSwipeEnabled()
{
return true;
}
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
{
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = 0;
return ItemTouchHelper.Callback.makeMovementFlags(dragFlags, swipeFlags);
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target)
{
if (source.getItemViewType() != target.getItemViewType())
{
return false;
}
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i)
{
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)
{
// We only want the active item to change
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE)
{
// Let the view holder know that this item is being moved or dragged
((ItemView) viewHolder).onItemSelected();
}
super.onSelectedChanged(viewHolder, actionState);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
{
super.clearView(recyclerView, viewHolder);
// Tell the view holder it's time to restore the idle state\
((ItemView) viewHolder).onItemClear();
}
}
Yet somehow whenever I try to scroll it stops the second I lift my finger. How do I get it to continue trying to scroll.
Remove the ScrollView from your layout, and don't use wrap_content for the RecyclerView's height. RecyclerView already provides scrolling by itself, and you can use whatever layout_ attributes you had on the ScrollView to make the RecyclerView the right size.
You wrote this:
I have a RecyclerView in a ScrollView
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scroll">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/items"/>
But RecyclerView already supports fling, remove ScrollView from xml file. And set the height of RecyclerView match_parent, like below:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/items"/>
While using scroll view you need to off nestedscroll enable.
recyclerview.setNestedScrollingEnabled(false);
1- Change ScrollView to NestedScrollView
2- Use app:layout_behavior="#string/appbar_scrolling_view_behavior" in both Recyclerview and NestedScrollView
<NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:id="#+id/scroll">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:id="#+id/items"/>
3- Use recyclerview.setNestedScrollingEnabled(false);
I have two RecyclerViews on my screen. And I need to scroll both at the same time on the same distance programmatically. But if I do it fast - the RecyclerViews desynchronizes.
In this source code you should fast click on button in the right top and will see the result.
This is Activity, where button listener for scrolling lists created:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView1;
private RecyclerView recyclerView2;
private Adapter adapter1;
private Adapter adapter2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView1 = findViewById(R.id.recycler_view1);
recyclerView2 = findViewById(R.id.recycler_view2);
adapter1 = new Adapter();
recyclerView1.setLayoutManager(new LinearLayoutManager(this));
recyclerView1.setAdapter(adapter1);
adapter2 = new Adapter();
recyclerView2.setLayoutManager(new LinearLayoutManager(this));
recyclerView2.setAdapter(adapter2);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recyclerView1.smoothScrollBy(0, 400);
recyclerView2.smoothScrollBy(0, 400);
}
});
}
}
Adapter for lists:
public class Adapter extends RecyclerView.Adapter<Adapter.Holder>{
private boolean changeHeight = false;
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
holder.setContent(String.valueOf(position), position % 2 == 0 ? R.color.colorPrimary : R.color.colorAccent);
if (changeHeight && position == 3) holder.changeHeight();
}
#Override
public int getItemCount() {
return 100;
}
class Holder extends RecyclerView.ViewHolder {
private View view;
private TextView textView;
public Holder(View itemView) {
super(itemView);
view = itemView;
textView = itemView.findViewById(R.id.text_view);
}
public void setContent(String text, int colorRes) {
textView.setText(text);
textView.setBackgroundResource(colorRes);
}
public void changeHeight() {
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = view.getHeight() * 2;
view.setLayoutParams(params);
}
}
}
This is activity_main.xml layout for Activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view1"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view2"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"/>
<Button
android:id="#+id/button"
android:layout_width="100dp"
android:layout_height="100dp"/>
</LinearLayout>
Item for RecyclerView item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"/>
</RelativeLayout>
Crude solution is copying scroll of first recycler into the second one:
recyclerView1.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
recyclerView2.scrollBy(dx, dy);
}
});
Then proceed to smoothScroll only recyclerView1.
i already success to make one Recyclerview and i want to add new Recyclerview Horizontal on top. i will explain in my code :
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
id:arrayList is my first Recyclerview have name xml feeds_listview
id:arrayListUser is my new Recyclerview, i want make this Recyclerview Horizontal
xml for new Recylerview is feeds_listviewUser
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profil"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="#drawable/cthprofil" />
<TextView
android:id="#+id/fullName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="20"
android:text="Megi Fernanda"
android:textSize="17sp"
android:textColor="#color/colordefault"
android:textStyle="bold" />
</LinearLayout>
and this is my class adapter
public class FeedsCustomAdapter extends RecyclerView.Adapter<FeedsCustomAdapter.ViewHolder> {
private Context context;
private List<FeedsAdapter> feeds_list;
private ArrayList<Feeds> mFeedsList = new ArrayList<Feeds>();
private OnItemClickListener mListener;
private OnItemClickListener mListener2;
public FeedsCustomAdapter(Context context, ArrayList<Feeds> mFeedsList) {
this.context = context;
this.mFeedsList = mFeedsList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.feeds_listview, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Feeds feed = getFeeds().get(position);
int textColor = context.getResources().getColor(R.color.btn_next);
int textColor2 = context.getResources().getColor(R.color.text_color_black);
holder.fullName.setText(feed.user.fullName);
holder.location.setText(feed.user.location);
holder.topic.setText(Html.fromHtml( "Menyelesaikan Tantangan " + " <font color = '" + String.valueOf(textColor2) + "'>" + feed.topic + "</font>" ) );
Picasso.with(context)
.load(feed.user.avatar)
.into(holder.profile);
PrettyTime prettyTime = new PrettyTime();
String times = prettyTime.format(DateUtil.timeMilisTodate(feed.timestamp * 1000));
holder.times.setText(times);
}
#Override
public int getItemCount() {
return mFeedsList.size();
}
public ArrayList<Feeds> getFeeds() {
return mFeedsList;
}
public void setComplete(int position) {
mFeedsList.get(position).isComplete = 1;
}
public boolean last() {
boolean result = false;
int total = mFeedsList.size();
for (int i = 0; i < mFeedsList.size(); i++) {
if (mFeedsList.get(i).isComplete == 1) {
total--;
}
}
if (total == 1) {
result = true;
}
return result;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView fullName;
public TextView location;
public TextView topic;
public ImageView profile;
public TextView times;
public ViewHolder(View itemView) {
super(itemView);
fullName = (TextView) itemView.findViewById(R.id.fullName);
location = (TextView) itemView.findViewById(R.id.location);
topic = (TextView) itemView.findViewById(R.id.topic);
profile = (ImageView) itemView.findViewById(R.id.profil);
times = (TextView) itemView.findViewById(R.id.times);
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener2 != null){
mListener2.onItemClick2(v ,getPosition());
}
}
});
topic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null){
mListener.onItemClick(v ,getPosition());
}
}
});
}
}
public void setClickListener(OnItemClickListener clickListener) {
this.mListener = clickListener;
}
public void setClickListenerProfile(OnItemClickListener clickListener2){
this.mListener2 = clickListener2;
}
public interface OnItemClickListener {
public abstract void onItemClick(View view, int position);
public abstract void onItemClick2(View view, int position);
}
so, in my code i success to display first recylerview with my first xml and i want add new recylerview horizontal with new xml feeds_listviewUser
You can use LinearLayout to wrap both recyclerView.
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
And assign horizontal layout manager to one recyclerview and vertical layout manager to other
LinearLayoutManager userManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
arrayListUser.setLayoutManager(userManager);
LinearLayoutManager listManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
arrayList.setLayoutManager(listManager);
Put your recyclerviews in Relative layout.
First add horizontal recyclerView to alignParentTop true and fix height according to visibility of feeds_listviewUser next add vertical recyclerView with layout_below horizontal recyclerview id.
I have a nested scrollview as parent and 2 recyclerviews as its children. What my issue is the recycler view draws it's children at one shot instead of drawing on scroll. How can I prevent this. I read that if we add
android:nestedScrollingEnabled="false"
property this issue comes. But I added this property to make the scroll smoother. Given below is my xml file.
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/color_fafafa"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:paddingLeft="#dimen/dp_5"
android:paddingRight="#dimen/dp_5"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Can anybody tell me how can I solve this issue?
If you only have 2 RecyclerViews as children I would suggest removing one and and using RecyclerViews ViewType.
Use an Adapter like this:
public class ExampleAdapter extends RecyclerView.Adapter<BindableViewHolder> {
private static final int VIEW_TYPE_CLASS_A = 0;
private static final int VIEW_TYPE_CLASS_B = 1;
private List<ClassA> class_a_list;
private List<ClassB> class_b_list;
public ExampleAdapter(List<ClassA> class_a_list, List<ClassB> class_b_list) {
this.class_a_list = class_a_list;
this.class_b_list = class_b_list;
}
#Override
public BindableViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case VIEW_TYPE_CLASS_A:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_class_a, parent, false);
return new ClassAHolder(view);
default:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_class_b, parent, false);
return new ClassBHolder(view);
}
}
#Override
public void onBindViewHolder(BindableViewHolder holder, int position) {
if(position < class_a_list.size()) {
((ClassAHolder) holder).bind(class_a_list.get(position));
} else {
((ClassBHolder) holder).bind(class_b_list.get(position - class_a_list.size()));
}
}
#Override
public int getItemCount() {
return class_a_list.size() + class_b_list.size();
}
#Override
public int getItemViewType(int position) {
if(position < class_a_list.size()) {
return VIEW_TYPE_CLASS_A;
} else {
return VIEW_TYPE_CLASS_B;
}
}
}
With the help of getItemViewType(int position) you determine which kind of View there should be in the specific position.
Then you can use ViewHolders like these:
public abstract class BindableViewHolder<T> extends RecyclerView.ViewHolder {
public BindableViewHolder(View itemView) {
super(itemView);
}
public abstract void bind(T data);
}
public class ClassAHolder extends BindableViewHolder<ClassA> {
public ClassAHolder(View itemView) {
super(itemView);
}
#Override
public void bind(ClassA data) {
// populate your views
}
}
public class ClassBHolder extends BindableViewHolder<ClassB> {
public ClassBHolder(View itemView) {
super(itemView);
}
#Override
public void bind(ClassB data) {
// populate your views
}
}