I updated to firebase-ui 6.3.0 which doesn't have the populateViewHolder method anymore. I changed the code according to the examples I found online. RecycleView didn't show anything until I added adapter.startListening() to the onStart method of my home activity.
The problem is that only 1 item is displayed and can't figure it out why. Since I use linearLayoutManager.setStackFromEnd(true) the item displayed is the last item, but if I comment out that line the first item is displayed (and the context manu doesn't work either).
I checked some similiar StackOverflow questions but couldn't find the problem.
Firebase RecyclerView OnDataChanged only last element is Shown
Recycler View showing only very last item added to realtime database
Here are my classes and xmls:
HomeActivity:
private RecyclerView transactionsRecyclerView;
private TransactionRecordAdapter transactionRecordAdapter;
private FirebaseHelper firebaseHelper;
private Query query;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
firebaseHelper = new FirebaseHelper();
query = this.firebaseHelper.getTransactionRecordsOrderedByDateQuery();
// FirebaseDatabase.getInstance().getReference().child(ConstantStringValue.DB_CHILD_TRANSACTION_RECORDS).child(auth.getCurrentUser().getUid())
// .orderByChild("date");
transactionsRecyclerView = findViewById(R.id.transactionsRecyclerView);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
transactionsRecyclerView.setLayoutManager(linearLayoutManager);
DividerItemDecoration itemDecoration = new DividerItemDecoration(this, VERTICAL);
transactionsRecyclerView.addItemDecoration(itemDecoration);
registerForContextMenu(transactionsRecyclerView);
}
#Override
protected void onStart() {
super.onStart();
transactionRecordAdapter = new TransactionRecordAdapter(TransactionRecord.class, query, this);
transactionsRecyclerView.setAdapter(transactionRecordAdapter);
transactionRecordAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
transactionRecordAdapter.stopListening();
}
TransactionRecordAdapter:
private int position;
private String selectedItemId;
private Context context;
public TransactionRecordAdapter(Class<TransactionRecord> modelClass, Query ref, Context context) {
super(new FirebaseRecyclerOptions.Builder<TransactionRecord>()
.setQuery(ref, modelClass)
.build());
this.context = context;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public String getSelectedItemId() {
return selectedItemId;
}
public void setSelectedItemId(String selectedItemId) {
this.selectedItemId = selectedItemId;
}
#Override
protected void onBindViewHolder(#NonNull final TransactionRecordViewHolder holder, int position,
#NonNull TransactionRecord model) {
holder.itemView.setOnLongClickListener(v -> {
setPosition(holder.getAdapterPosition());
setSelectedItemId(holder.getId());
return false;
});
holder.setAnnouncement(model.getAnnouncement());
...
holder.setId(this.getRef(position).getKey());
}
#NonNull
#Override
public TransactionRecordViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.transrecord, parent, false);
return new TransactionRecordViewHolder(view);
}
#Override
public void onViewRecycled(TransactionRecordViewHolder holder) {
holder.itemView.setOnLongClickListener(null);
super.onViewRecycled(holder);
}
TransactionRecordViewHolder:
private View view;
private String id;
public TransactionRecordViewHolder(View itemView) {
super(itemView);
view = itemView;
view.setOnCreateContextMenuListener(this);
}
// ... setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
contextMenu.add(Menu.NONE, R.id.editTransHomeContext,
Menu.NONE, "Szerkesztés");
contextMenu.add(Menu.NONE, R.id.deleteTransHomeContext,
Menu.NONE, "Törlés");
}
activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context="hu.beczdev.cashbudget.activity.HomeActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/transactionsRecyclerView" />
</LinearLayout>
transrecord.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/transAmountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:paddingStart="25dp"
android:paddingTop="10dp"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="#+id/transDateTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:paddingTop="10dp"
android:paddingEnd="25dp"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:paddingStart="25dp"
android:textStyle="bold"
android:id="#+id/transCatNameTextView"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:textSize="15sp"
android:paddingStart="25dp"
android:id="#+id/transCommentView"/>
</LinearLayout>
</LinearLayout>
I think your issue not in firebase as it already returned a row, you at least need to wrap_content of the height of your list item to not occupy the entire height of the RecyclerView.
so in transrecord.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
Related
I have a RecyclerView inside BottomSheetDialogFragment. The RecyclerView items touch working normally when it's scrolling slowly.
But when the RecyclerView is scrolled fast and after the list stops (without touching), than touching on any item doesn't work on fast touch. It needs double touching.
See in the below example gif, when touching on Andhra Pradesh it's working fine. After slow scrolling, touching on Haryana also works fine. Then doing a fast scroll and touching on Punjab doesn't work on the first touch. Touching again it works.
Following is the code:
OperatorListDialogFragment.java
package com.*;
import *;
public class OperatorListDialogFragment extends BottomSheetDialogFragment{
private static final String ARG_NAME = "item_name";
private static final String ARG_LOGO = "item_logo";
private Listener mListener;
private String header;
private Context mContext;
public static OperatorListDialogFragment newInstance(String[] name, int[] logo, String header) {
final OperatorListDialogFragment fragment = new OperatorListDialogFragment();
final Bundle args = new Bundle();
args.putStringArray(ARG_NAME, name);
args.putIntArray(ARG_LOGO, logo);
args.putString("header", header);
fragment.setArguments(args);
return fragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_operator_list_dialog_list_dialog, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
TextView headerTV = view.findViewById(R.id.title);
headerTV.setText(getArguments().getString("header"));
final RecyclerView recyclerView = view.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(new OperatorAdapter(getArguments().getStringArray(ARG_NAME), getArguments().getIntArray(ARG_LOGO)));
view.findViewById(R.id.dismiss).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
final Fragment parent = getParentFragment();
if (parent != null) {
mListener = (Listener) parent;
} else {
mListener = (Listener) context;
}
}
#Override
public void onDetach() {
mListener = null;
super.onDetach();
}
public interface Listener {
void onFilterSelected(String selected, String selectedQuery);
}
private class ViewHolder extends RecyclerView.ViewHolder {
final TextView text;
ImageView logo;
ViewHolder(LayoutInflater inflater, ViewGroup parent) {
// TODO: Customize the item layout
super(inflater.inflate(R.layout.fragment_operator_list_dialog_list_dialog_item, parent, false));
text = itemView.findViewById(R.id.tv_operator_name);
logo = itemView.findViewById(R.id.iv_recharge_provider_icon);
}
}
private class OperatorAdapter extends RecyclerView.Adapter<ViewHolder> {
private String[] mNames;
private int[] mLogos;
OperatorAdapter(String[] name, int[] logo) {
mNames = name;
mLogos = logo;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.text.setText(mNames[position]);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("clicked", "" + position);
}
});
}
#Override
public int getItemCount() {
return mNames.length;
}
}
}
dialog.xml
<?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_height="match_parent"
android:layout_width="match_parent"
>
<ImageView
android:focusable="true"
android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Close"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="#+id/dismiss"
android:padding="14dp"
android:src="#drawable/ic_close_black_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/title"
app:layout_constraintTop_toTopOf="#id/dismiss"
app:layout_constraintBottom_toBottomOf="#id/dismiss"
app:layout_constraintLeft_toRightOf="#id/dismiss"
android:padding="14dp"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
tools:text="Select operator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<View
app:layout_constraintTop_toBottomOf="#id/dismiss"
android:background="#969696"
android:layout_width="match_parent"
android:layout_height="0.5dp"/>
<androidx.recyclerview.widget.RecyclerView
app:layout_constraintTop_toBottomOf="#id/dismiss"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_constrainedHeight="true"
android:paddingTop="#dimen/list_item_spacing_half"
android:paddingBottom="#dimen/list_item_spacing_half"
tools:context=".fragments.OperatorListDialogFragment"
tools:listitem="#layout/fragment_operator_list_dialog_list_dialog_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
recycler_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:gravity="center_vertical"
android:orientation="horizontal"
android:id="#+id/ll_operator_list_wrapper"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:visibility="gone"
android:layout_marginLeft="16dp"
android:id="#+id/iv_recharge_provider_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginVertical="16dp"
android:layout_centerVertical="true"
android:src="#drawable/ic_bsnl_logo"
tools:visibility="visible"/>
<TextView
android:padding="16dp"
android:textColor="#212121"
android:textSize="14sp"
android:ellipsize="end"
android:id="#+id/tv_operator_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:text="BSNL"
android:layout_toRightOf="#+id/iv_recharge_provider_icon"
android:layout_centerInParent="true"/>
<View
android:layout_below="#id/iv_recharge_provider_icon"
android:id="#+id/divider0"
android:background="#eeeeee"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginLeft="16dp"
android:layout_toRightOf="#+id/iv_recharge_provider_icon"
/>
</RelativeLayout>
add android:nestedScrollingEnabled="false" in RecyclerView
I want to make clicklistener on cardview in my viewpager to startActivity(Intent)
i've tried to make clicklistener with position in setOnPageChangeListener method, but it does not work for me. Please help.
I want to set Intent on cardview.clicklistener, but i don't understand how to set by position, wheter using swith or if method
HERE MY ACTIVITY CODE :
public class Activity extends AppCompatActivity {
ViewPager viewPager;
Adapter adapter;
List<Model> models;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
CardView cardView = findViewById(R.id.cardViewLogin);
//ImageViewPager
models = new ArrayList<>();
models.add(new Model(R.drawable.m,"title", "desc"));
models.add(new Model(R.drawable.d,"title", "desc"));
models.add(new Model(R.drawable.a,"title", "desc"));
adapter = new Adapter(models,this);
viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(adapter);
viewPager.setPadding(130,0,130,0);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(final int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(final int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
HERE MY ADAPTER CODE :
public class Adapter extends PagerAdapter {
private List<Model> models;
private LayoutInflater layoutInflater;
private Context context;
public Adapter(List<Model> models, Context context) {
this.models = models;
this.context = context;
}
#Override
public int getCount() {
return models.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view.equals(object);
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position)
{
layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.item,container,false);
ImageView imageView;
TextView title, desc;
imageView = view.findViewById(R.id.image);
title = view.findViewById(R.id.title);
desc = view.findViewById(R.id.desc);
imageView.setImageResource(models.get(position).getImage());
title.setText(models.get(position).getTitle());
desc.setText(models.get(position).getDesc());
container.addView(view,0);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position,
#NonNull Object object) {
container.removeView((View)object);
}
HERE IS MY item.xml CODE :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<androidx.cardview.widget.CardView
android:id="#+id/cardViewLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="20dp"
android:layout_margin="8dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="400dp">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:src="#drawable/hourglass"
android:layout_height="200dp"
android:scaleType="centerInside"
android:layout_margin="10dp"/>
<TextView
android:id="#+id/title"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/image"
android:layout_marginTop="10dp"
android:layout_marginStart="16dp"
android:text="Title"
android:textSize="16sp"/>
<View
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/cardview_shadow_start_color"
android:layout_margin="10dp"
android:layout_below="#+id/title"/>
<TextView
android:id="#+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/separator"
android:layout_marginTop="3dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="20dp"
android:maxLines="3"
android:drawablePadding="10dp"
android:ellipsize="end"
android:text="Description"
android:textSize="16sp"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
HERE IS MY XML ACTIVITY LAYOUT CODE :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".UserLoginActivity">
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundGravity="center"
android:layout_gravity="center"
android:overScrollMode="never"
android:clipToPadding="false">
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>
onClick listener of cardView
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int pos=viewPager.getCurrentItem();
//used switch case
switch (pos) {
case 0:
//Do whatever you want
break;
case 1:
//Do whatever you want
break;
}
});
I want to show a list of strings, this list has to be vertically scrollable, and for each row a variable number of columns, this column with will depend on the string with. So it will be a grid vertically scrollable.
So Graphically I want to achieve this :
What I'm getting as a result is a horizontally scrollable list, with 3 rows and many columns, and what I want is the other way around : NOT horizontally scrollable (many columns, depending on the team name) but vertically scrollable.
In order to get this I've added a StaggeredGridLayoutManager to the recycler view with 3 span count (this might be wrong) and StaggeredGridLayoutManager.GAP_HANDLING_NONE to have as many columns as I can.
First question would be is it possible to achieve this with StaggeredGridLayoutManager? If yes how can I fix my problem? Any suggestion or idea is welcome.
Note that the item in the xml has a max width and then it ellipsizes
What I have is the following :
item_team.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="title"
type="String" />
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_small"
android:background="#drawable/club_background"
android:padding="#dimen/margin_general">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:maxWidth="184dp"
android:gravity="center"
android:lines="1"
android:text="#{title}"
tools:text="Arsenal" />
</RelativeLayout>
TeamAdapter.java :
public class TeamAdapter extends ListAdapter<TeamItem, RecyclerView.ViewHolder> {
private LayoutInflater inflater;
private List<TeamItem> items = new ArrayList<>();
private static final DiffUtil.ItemCallback<TeamItem> ITEM_CALLBACK = new DiffUtil.ItemCallback<TeamItem>() {
#Override
public boolean areItemsTheSame(#NonNull TeamItem item1, #NonNull TeamItem item2) {
return item1.hashCode() == item2.hashCode();
}
#Override
public boolean areContentsTheSame(#NonNull TeamItem item1, #NonNull TeamItem item2) {
return item1.id.equalsIgnoreCase(item2.id);
}
};
private static final int VIEW_TYPE_TEAM = 0;
public TeamAdapter(Context context) {
super(ITEM_CALLBACK);
inflater = LayoutInflater.from(context);
}
public void setTeams(List<TeamItem> teams) {
items = teams;
notifyDataSetChanged();
}
public class TeamViewHolder extends RecyclerView.ViewHolder {
private final ItemTeamBinding binding;
TeamViewHolder(ItemTeamBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void bind(TeamItem team) {
binding.setTitle(team.name);
binding.executePendingBindings();
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_TEAM:
ItemTeamBinding itemTeamBinding = DataBindingUtil.inflate(inflater, R.layout.item_team, parent, false);
return new TeamItemViewHolder(itemTeamBinding);
}
throw new RuntimeException("There are invalid view types in TeamAdapter!");
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, final int position) {
switch (viewHolder.getItemViewType()) {
case VIEW_TYPE_TEAM:
((TeamItemViewHolder) viewHolder).bind(items.get(position));
break;
}
}
#Override
public int getItemCount() {
if (items != null && !items.isEmpty()) {
return items.size();
}
return super.getItemCount();
}
#Override
public int getItemViewType(int position) {
if (items != null && !items.isEmpty()) {
return VIEW_TYPE_TEAM;
}
return super.getItemViewType(position);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="activity"
type="com.ziniestro.base.activity.MainActivity" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/tlbMain"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:navigationIcon="#null">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin_large"
android:paddingTop="#dimen/margin_large"
android:paddingBottom="#dimen/margin_large"
android:text="#string/main_title" />
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin_medium"
android:layout_marginTop="#dimen/margin_small"
android:layout_marginEnd="#dimen/margin_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:background="#drawable/round_border_station_preference"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imgMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="#dimen/margin_medium"
android:layout_marginTop="#dimen/margin_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:src="#drawable/ic_title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="#dimen/margin_large"
android:layout_marginTop="#dimen/margin_xlarge"
android:layout_toEndOf="#+id/imgMain"
android:gravity="center|start"
android:text="#string/main_title" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcyMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutAnimation="#anim/layout_anim_scale"
tools:listitem="#layout/item_team" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
public TeamAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setActivity(this);
binding.tlbMain.setTitle(Constants.EMPTY_STRING);
final Drawable backIcon = ContextCompat.getDrawable(this, R.drawable.ic_arrow_back);
backIcon.setColorFilter(ContextCompat.getColor(this, R.color.secondary) + 0xFF000000, PorterDuff.Mode.SRC_ATOP);
binding.tlbMain.setNavigationIcon(backIcon);
setSupportActionBar(binding.tlbMain);
adapter = new TeamAdapter(this);
if(MainApplication.getInstance().teamFeed.items !=null && !MainApplication.getInstance().teamFeed.items.isEmpty()) {
adapter.setTeams(MainApplication.getInstance().teamFeed.items);
StaggeredGridLayoutManager gridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.GAP_HANDLING_NONE);
binding.rcyMain.setLayoutManager(gridLayoutManager);
binding.rcyMain.setHasFixedSize(true);
binding.rcyMain.setAdapter(adapter);
binding.rcyMain.setNestedScrollingEnabled(false);
}
}
}
I think that you want is the FlexboxLayoutManager https://github.com/google/flexbox-layout#flexboxlayoutmanager-within-recyclerview With the Wrap option in a Vertical Recyclerview.
The "Cells" that contain the Strings you want can vary in size and if it cannot fit a Cell on to the line it wraps it to the next line.
I am using RecyclerView to show some data in form of list, but the data won't display.
Following is my code, I am using to implement RecyclerView
public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{
String[] c_names={"INDIA","US","UK","AUSTRALIA","CHINA","JAPAN"};
int[] c_flags={R.drawable.india,R.drawable.india,R.drawable.india,R.drawable.india,R.drawable.india,R.drawable.india};
private RecyclerView recyclerView;
RecyclerAdapter recyclerAdapter;
ArrayList<Country> arrayList=new ArrayList<>();
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView=findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setHasFixedSize(true);
int count=0;
for(String Name:c_names){
arrayList.add(new Country(Name,c_flags[count]));
Log.i("ggg", "onCreate: "+arrayList.get(count).getName()+" "+arrayList.get(count).getFlag_id());
count++;
}
recyclerAdapter=new RecyclerAdapter(arrayList);
recyclerView.setAdapter(recyclerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main,menu);
MenuItem menuItem=menu.findItem(R.id.ction_search);
SearchView searchView= (SearchView) MenuItemCompat.getActionView(menuItem);
searchView.setOnQueryTextListener(this);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
newText=newText.toLowerCase();
ArrayList<Country> newList=new ArrayList<>();
for(Country country:arrayList){
String name=country.getName().toLowerCase();
if(name.contains(newText)){
newList.add(country);
}
}
recyclerAdapter.setFilter(newList);
return true;
}
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
ArrayList<Country> arrayList=new ArrayList<>();
public RecyclerAdapter(ArrayList<Country> arrayList) {
this.arrayList = arrayList;
}
#Override
public RecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,
parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerAdapter.MyViewHolder holder, int position) {
holder.c_flags.setImageResource(arrayList.get(position).getFlag_id());
holder.c_name.setText(arrayList.get(position).getName());
}
#Override
public int getItemCount() {
return arrayList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
ImageView c_flags;
TextView c_name;
public MyViewHolder(View itemView) {
super(itemView);
c_flags=itemView.findViewById(R.id.flag);
c_name=itemView.findViewById(R.id.name);
}
}
public void setFilter(ArrayList<Country> filter){
// filter=new ArrayList<>();
arrayList.addAll(filter);
notifyDataSetChanged();
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="pritish.sawant.com.filterrecyclerview.MainActivity">
<include layout="#layout/toolbar_layout"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview"/>
</LinearLayout>
row_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="4dp"
android:layout_marginBottom="8dp"
android:layout_marginRight="4dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="50dp"
android:elevation="5dp"
app:cardCornerRadius="8dp"
android:background="#9E9E9E"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:background="#9E9E9E">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="8dp"
android:scaleType="fitXY"
android:id="#+id/flag"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/flag"
android:layout_marginLeft="20dp"
android:gravity="center"
android:layout_centerVertical="true"
android:textSize="15dp"
android:textStyle="bold"
android:id="#+id/name"
android:textColor="#000000"
/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
toolbar_layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/colorPrimary"
android:id="#+id/toolbar"
app:theme="#style/ThemeOverlay.AppCompat.Dark">
</android.support.v7.widget.Toolbar>
My RecyclerView is blank.
I am showing the arrays mentioned in MainActivity in my RecyclerView. I tried a lot but couldn't figure out what am I doing wrong? Any help would be greatly appreciated.
You are missing orientation in parent layout.
<LinearLayout 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:orientation="vertical"
android:layout_height="match_parent"
tools:context="pritish.sawant.com.filterrecyclerview.MainActivity">
<include layout="#layout/toolbar_layout"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview"/>
</LinearLayout>
I am trying to use the SwipeDismissBehavoir from design support library. I've list items in RecyclerView and swiping an item have to dismiss (like google inbox app) .
I've set the listener for the RecyclerView items but the SwipeDismissBehavior onDismiss listener is not getting called.
SwipeDismissBehavior behavior = new SwipeDismissBehavior();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)mItemLayout.getLayoutParams();
params.setBehavior(behavior);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
#Override
public void onDismiss(View view) {
}
#Override
public void onDragStateChanged(int i) {
}
});
mItemLayout.setLayoutParams(params);
Here is example how delete row by swipe
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
// init layout manager
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
final ArrayList<String> list = new ArrayList<String>();
list.add("Item1");
list.add("Item2");
list.add("Item3");
list.add("Item4");
list.add("Item5");
list.add("Item6");
final MyAdapter adapter = new MyAdapter(list);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// callback for drag-n-drop, false to skip this feature
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// callback for swipe to dismiss, removing item from data and adapter
list.remove(viewHolder.getAdapterPosition());
adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
});
swipeToDismissTouchHelper.attachToRecyclerView(recyclerView);
}
Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<String> dataset_;
public static class MyViewHolder extends RecyclerView.ViewHolder{
public Button mBtn;
public TextView mTextView2;
public MyViewHolder(View v){
super(v);
mBtn = (Button) itemView.findViewById(R.id.delete);
mTextView2 = (TextView) itemView.findViewById(R.id.textView2);
}
}
public MyAdapter (ArrayList<String> dataset){
dataset_ = dataset;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(v);
return myViewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder,int position){
holder.mTextView2.setText(dataset_.get(position));
}
#Override
public int getItemCount(){
return dataset_.size();
}
}
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical"
android:padding="16dp">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/heading_dismissable_recycler_view" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Item in RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/textView2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/delete"
android:text="Delete"
android:layout_marginLeft="150dp"
android:visibility="invisible" />
</LinearLayout>
</LinearLayout>
Tried with single view.
I can know the view was dismissed, but I'm wondering how to restore the view like Gmail.
Layout:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/coordinatorLayout"
tools:context=".MainActivity">
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Haha"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v7.widget.CardView>
</android.support.design.widget.CoordinatorLayout>
Activity:
public class MainActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
private CardView cardView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
cardView = (CardView) findViewById(R.id.cardView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) cardView.getLayoutParams();
final SwipeDismissBehavior<CardView> behavior = new SwipeDismissBehavior();
behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
#Override
public void onDismiss(final View view) {
Snackbar.make(coordinatorLayout, "Done", Snackbar.LENGTH_LONG)
.show();
}
#Override
public void onDragStateChanged(int i) {
}
});
params.setBehavior(behavior);
cardView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return behavior.onTouchEvent(coordinatorLayout, cardView, event);
}
});
}
}
I have succeeded implementing the support library SwipeDismissBehavior and it actually requires CoordinatorLayout inside of each inflated card view layout. I haven't noticed any performance issues so far, so I assume CoordinatorLayout is not so heavy for the UI. There is probably a better way, but I still haven't found it.
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
android:background="#FF0000">
<LinearLayout
android:id="#+id/card_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#FFFFFF"
android:padding="20dp">
<TextView
android:id="#+id/card_context_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test text"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
In the constructor of the RecyclerView.ViewHolder implementation class (which is inside the Adapter) I have added:
View cardContentLayout = view.findViewById(R.id.card_content_layout);
SwipeDismissBehavior<View> swipeDismissBehavior = new SwipeDismissBehavior<>();
swipeDismissBehavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START);
swipeDismissBehavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
#Override
public void onDismiss(View view) {
int adapterPosition = getAdapterPosition();
deleteListener.onDismissGesture(view, adapterPosition);
}
#Override
public void onDragStateChanged(int state) { }
});
CoordinatorLayout.LayoutParams coordinatorParams = (CoordinatorLayout.LayoutParams) cardContentLayout.getLayoutParams();
coordinatorParams.setBehavior(swipeDismissBehavior);
cardContentLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return swipeDismissBehavior.onTouchEvent((CoordinatorLayout) itemView, cardContentLayout, event);
}
});