Code of the illustration:
mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.setReverseLayout(true);
mLinearLayoutManager.setStackFromEnd(true);
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
See illustration here
How can I add new items (in my case, messages) to the bottom of Recycler View and still keep the "gravity" of the view to the top?
So, what works now is the following:
The gravity of the view is at the top. That's good! ✓
What doesn't work:
New messages are added to the top of the view. That's bad ×
I want them to be added at the bottom of the view (after the previous message) like so:
See here
Try removing these two lines or setting them false
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
setStackFromEnd will set the view to show the last element, the layout direction will remain the same whereas setReverseLayout will change the order of the elements added by the Adapter.
Try using this to move your RecyclerView and EditText up when keyboard appears
<activity name="YourActivity"
android:windowSoftInputMode="stateHidden|adjustResize">
//stateHidden -> keyboard is hidden when you first open the activity
//adjustResize -> this will adjust the layout resize option
...
</activity>
in AndroidManifest.xml.
To hook the RecyclerView at top
<android.support.v7.widget.RecyclerView
android:id="#+id/messageRecyclerViewRep"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/linearLayout3"
android:layout_marginLeft="36dp"
android:scrollbars="vertical" />
To put the recyclerView at bottom first and push it up as the keyboard pops up.
<LinearLayout
android:id="#+id/recyclerContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/linearLayout3"
android:layout_above="#+id/linearLayout"
android:gravity="bottom">
<android.support.v7.widget.RecyclerView
android:id="#+id/messageRecyclerViewRep"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="36dp"
android:scrollbars="vertical" />
</LinearLayout>
To scroll the recyclerView to bottom when keyboard pops up i.e. when the recycler view's layout is changed ( You can do the same thing on Edit Text active or focused or clicked or something like that. I've done it on recycler view's layout change. )
recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) {
recyclerView.postDelayed(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(mAdapter.getItemCount());
}
}, 100);
}
}
});
setReverseLayout(true) this will reverse the item traversal & layout order.The first item will come to end not view or content.
setStackFromEnd(true) this will fill the recycler list content starting from the bottom of the view.
Need to setStackFromEnd(true) not setReverseLayout(true)
And in XML Recyclerview height should be match_parent
Below i have given working code.
activity xml
<?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:orientation="vertical">
<Button
android:id="#+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rcList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="true" />
</LinearLayout>
list item xml layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center_vertical">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content" android:textSize="23sp"
android:layout_height="wrap_content" android:textColor="#4a4883"
android:text="Test Text" />
</FrameLayout>
Adapter class
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private static final String TAG = "CustomAdapter";
private ArrayList<String> mDataSet;
private int size = 0;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View v) {
super(v);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Element " + getAdapterPosition() + " clicked.");
}
});
textView = (TextView) v.findViewById(R.id.textView);
}
public TextView getTextView() {
return textView;
}
}
public CustomAdapter(ArrayList<String> dataSet) {
mDataSet = dataSet;
if (mDataSet != null && !mDataSet.isEmpty()) {
size = mDataSet.size();
}
}
public void refreshData(String add) {
if (!TextUtils.isEmpty(add)) {
mDataSet.add(add);
size = mDataSet.size();
notifyDataSetChanged();
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.list_item, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
viewHolder.getTextView().setText(mDataSet.get(position));
}
#Override
public int getItemCount() {
return size;
}
}
Activity class
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
protected CustomAdapter mAdapter;
protected LinearLayoutManager mLayoutManager;
protected ArrayList<String> listString = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rcList);
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
/**
*setStackFromEnd true will fill the content(list item) from the bottom of the view
*/
mLayoutManager.setStackFromEnd(true);
mLayoutManager.setReverseLayout(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
findViewById(R.id.btnAdd).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int temp = mAdapter.getItemCount() + 1;
mAdapter.refreshData("Test text " + temp);
mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount());
}
});
mAdapter = new CustomAdapter(listString);
mRecyclerView.setAdapter(mAdapter);
}
}
The simplest way to achieve this would be to load the elements into the Recyclerview in the reverse order to how they are entered in the Firebase Database.
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
viewHolder.getTextView().setText(mDataSet.get(getItemCount() - 1 -position));
}
What this would do is that the item which is inserted last will get displayed at bottom since you are loading the items from top. No need for any change in any of the XMLs or any other code.
I had same issues with Recylerview not resizing itself when the keyboard pops up and therefore I resorted to this method.
All the best!!
I have implemented and here is my Implementation using FirebaseRecyclerView
you need to set this setStackFromEnd=true and setReverseLayout=true
my xml
Recycler View Holder
public class TestingFirebaseHolder extends RecyclerView.ViewHolder {
private TextView mTextView;
private TextView mTextView2;
public TestingFirebaseHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textViewTesting);
mTextView2 = itemView.findViewById(R.id.textViewTesting2);
}
public void setTextView(String text,String text2)
{
mTextView.setText(text);
mTextView2.setText(text2);
}
}
Testing Class
public class TestingUser {
public String UserName;
public String mUid;
public TestingUser() {
}
public TestingUser(String userName, String uid) {
UserName = userName;
mUid = uid;
}
}
Activity Code
private EditText mEditText;
private RecyclerView mRecyclerView;
private FirebaseRecyclerAdapter<TestingUser,TestingFirebaseHolder> mAdapter;
private FirebaseUser mUser;
private DatabaseReference mReference;
mEditText = findViewById(R.id.testingEditText);
mRecyclerView = findViewById(R.id.hello_rec);
mUser = FirebaseAuth.getInstance().getCurrentUser();
mReference = FirebaseDatabase.getInstance().getReference();
LinearLayoutManager ll = new LinearLayoutManager(this);
ll.setReverseLayout(true); // set this
ll.setStackFromEnd(true); // set this
mRecyclerView.setLayoutManager(ll);
Query query = mReference.child("Testing").child(mUser.getUid()).orderByValue();
mAdapter = new FirebaseRecyclerAdapter<TestingUser, TestingFirebaseHolder>(
TestingUser.class,R.layout.testing_recycler_layout,TestingFirebaseHolder.class,query
) {
#Override
protected void populateViewHolder(TestingFirebaseHolder viewHolder, TestingUser model, int position) {
viewHolder.setTextView(model.mUid,model.UserName);
}
};
mRecyclerView.setAdapter(mAdapter);
public void buttonClick(View view) {
if(!mEditText.getText().toString().isEmpty())
{
TestingUser user = new TestingUser("Salman",mEditText.getText().toString());
mReference.child("Testing").child(mUser.getUid()).push().setValue(user);
mEditText.setText("");
}
}
Result is
link
Try this, it works for me.
mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.stackFromEnd(true)
mLinearLayoutManager.isSmoothScrollbarEnabled(true)
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
Related
Ok I've been pondering this all weekend and I'm running in circles and confusing myself about it; so someone please help. Here's the scoop: I have an app with a RecyclerView to hold CardView items. Here is the layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scene_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="4dp"
app:cardBackgroundColor="#75757A">
<RelativeLayout
android:id="#+id/listItemWrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<TextView
android:id="#+id/assetSymbol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="SYM"
android:textColor="#android:color/white"
android:textSize="20sp"
android:textStyle="bold">
</TextView>
<TextView
android:id="#+id/assetPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_toEndOf="#+id/assetSymbol"
android:text="$1,000.00"
android:textColor="#android:color/white"
android:textSize="20sp"
android:textStyle="bold"
android:layout_toRightOf="#+id/assetSymbol">
</TextView>
<ImageView
android:id="#+id/imageView"
android:layout_width="30sp"
android:layout_height="30sp"
android:layout_margin="8dp"
android:layout_toEndOf="#+id/assetPrice"
android:padding="2dp"
android:layout_toRightOf="#+id/assetPrice">
</ImageView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/openShort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/assetPrice"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:backgroundTint="#color/bearRed"
android:clickable="true"
android:visibility="gone"
app:fabSize="mini"
app:srcCompat="#drawable/ic_bear_enter" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/openLong"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/assetPrice"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toStartOf="#+id/openShort"
android:layout_toLeftOf="#+id/openShort"
android:backgroundTint="#color/bullGreen"
android:clickable="true"
android:visibility="gone"
app:fabSize="mini"
app:srcCompat="#drawable/ic_bull_enter" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/deleteAsset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/assetPrice"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toStartOf="#+id/openLong"
android:layout_toLeftOf="#+id/openLong"
android:backgroundTint="#color/colorPrimary"
android:clickable="true"
android:visibility="gone"
app:fabSize="mini"
app:srcCompat="#drawable/ic_delete_asset" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/editAsset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/assetPrice"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toStartOf="#+id/deleteAsset"
android:layout_toLeftOf="#+id/deleteAsset"
android:backgroundTint="#color/colorPrimary"
android:clickable="true"
android:visibility="gone"
app:fabSize="mini"
app:srcCompat="#drawable/ic_edit_asset" />
</RelativeLayout>
<ImageView
android:id="#+id/showOptions"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:layout_gravity="end"
android:layout_margin="8dp"
app:srcCompat="#drawable/ic_baseline_more_vert" />
</androidx.cardview.widget.CardView>
You'll notice that the card contains four floating action buttons, which are initially hidden. What I'm trying to do is have the buttons animate into view when the user clicks the "show options" ImageView (android:id="#+id/showOptions"). Here is all the relevant code snippets:
MainActivity.java
public class MainActivity extends AppCompatActivity implements OnClickListener {
private ArrayList<WatchListItem> watchListArray;
private RecyclerView watchList;
private WatchListAdapter listAdapter;
private RecyclerView.LayoutManager listManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
watchListArray = new ArrayList<>();
watchList = (RecyclerView) findViewById(R.id.watchList);
watchList.setHasFixedSize(true);
listManager = new LinearLayoutManager(this);
watchList.setLayoutManager(listManager);
listAdapter = new WatchListAdapter(watchListArray);
watchList.setAdapter(listAdapter);
}
public void engage(Asset asset) {
int position = watchListArray.size();
String ticker = asset.getSymbol();
//Double.toString(asset.getCurrentPrice()) replaced with fixed value for testing
String price = "390.55";
//int indicator set to fixed value for testing
int indicator = R.drawable.ic_bull_indicator;
watchListArray.add(position, new WatchListItem(indicator, price, ticker));
listAdapter.notifyItemInserted(position);
listAdapter.setOnItemClickListener(new WatchListAdapter.OnItemClickListener() {
#Override
public void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
expandListItem(position, show, edit, delete, oLong, oShort);
}
});
}
public void expandListItem(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
if (edit.getVisibility() == View.GONE) {
show.setImageResource(R.drawable.ic_collapse);
oShort.animate().alpha(1f).setDuration(150);
oLong.animate().alpha(1f).setStartDelay(125).setDuration(150);
delete.animate().alpha(1f).setStartDelay(250).setDuration(150);
edit.animate().alpha(1f).setStartDelay(375).setDuration(150);
} else {
edit.animate().alpha(0f).setDuration(150);
delete.animate().alpha(0f).setStartDelay(125).setDuration(150);
oLong.animate().alpha(0f).setStartDelay(250).setDuration(150);
oShort.animate().alpha(0f).setStartDelay(375).setDuration(150);
show.setImageResource(R.drawable.ic_baseline_more_vert);
}
listAdapter.notifyItemChanged(position);
}
WatchListAdapter.java
public class WatchListAdapter extends RecyclerView.Adapter<WatchListAdapter.WatchListViewHolder> {
private ArrayList<WatchListItem> mWatchList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public static class WatchListViewHolder extends RecyclerView.ViewHolder {
public TextView mAssetSymbol;
public TextView mAssetPrice;
public ImageView mImageView;
public ImageView mShowOptions;
public FloatingActionButton mEditAsset;
public FloatingActionButton mDeleteAsset;
public FloatingActionButton mOpenLong;
public FloatingActionButton mOpenShort;
public WatchListViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
mAssetSymbol = itemView.findViewById(R.id.assetSymbol);
mAssetPrice = itemView.findViewById(R.id.assetPrice);
mImageView = itemView.findViewById(R.id.imageView);
mShowOptions = itemView.findViewById(R.id.showOptions);
mEditAsset = itemView.findViewById(R.id.editAsset);
mDeleteAsset = itemView.findViewById(R.id.deleteAsset);
mOpenLong = itemView.findViewById(R.id.openLong);
mOpenShort = itemView.findViewById(R.id.openShort);
mShowOptions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
int position = getAdapterPosition();
ImageView show = mShowOptions;
FloatingActionButton edit = mEditAsset;
FloatingActionButton delete = mDeleteAsset;
FloatingActionButton oLong = mOpenLong;
FloatingActionButton oShort = mOpenShort;
if (position != RecyclerView.NO_POSITION) {
listener.onShowOptionsClick(position, show, edit, delete, oLong, oShort);
}
}
}
});
}
}
public WatchListAdapter(ArrayList<WatchListItem> watchListArray) {
mWatchList = watchListArray;
}
#NonNull
#Override
public WatchListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new WatchListViewHolder(v, mListener);
}
#Override
public void onBindViewHolder(#NonNull WatchListViewHolder holder, int position) {
WatchListItem currentItem = mWatchList.get(position);
holder.mAssetSymbol.setText(currentItem.getAssetSymbol());
holder.mAssetPrice.setText(currentItem.getAssetPrice());
holder.mImageView.setImageResource(currentItem.getImageResource());
}
#Override
public int getItemCount() {
return mWatchList.size();
}
}
WatchListItem.java
public class WatchListItem {
private int mImageResource;
private String mAssetPrice;
private String mAssetSymbol;
public WatchListItem(int imageResource, String assetPrice, String assetSymbol) {
mImageResource = imageResource;
mAssetPrice = assetPrice;
mAssetSymbol = assetSymbol;
}
public int getImageResource() {
return mImageResource;
}
public String getAssetPrice() {
return mAssetPrice;
}
public String getAssetSymbol() {
return mAssetSymbol;
}
}
Quick note about the placement of listAdapter.setOnItemClickListener in MainActivity.java: initially this was included in the onCreate() method because that is where the RecyclerView is built and also where it was placed in the tutorial I was trying to follow; but I moved it to the engage() method because this is where the list item is added and I figured it didn't make sense to set the listener before the item even existed, right? Anyway let me know if this is incorrect, as I suspect it is, though regardless this did not change the behavior in testing
So here's the problem: App opens just fine, adds the item to the RecyclerView, but when I click the dropdown ImageView, nothing. Well not exactly nothing, I can tell it's trying to do something, but ultimately nothing happens. The best way I can describe it is that the CardView kind of "flashes" and the ImageView icon is briefly changed to the new icon but instantly changes back, and that's it. No errors, no crashes; just not performing the specified action and I cannot figure out why. I don't know why they had to deprecate ListView because this all would be a lot less confusing to me if I didn't have to build the onClickListener interface from scratch, but I digress. Thank you so much for taking the time to read all this and offering your valuable input.
Try the following code, see if it helps. I've changed some code in both files. You're now not creating a new listener every time an item is added, which might help.
MainActivity.java
public class MainActivity extends AppCompatActivity implements OnClickListener {
private ArrayList<WatchListItem> watchListArray;
private RecyclerView watchList;
private WatchListAdapter listAdapter;
private RecyclerView.LayoutManager listManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
watchListArray = new ArrayList<>();
watchList = (RecyclerView) findViewById(R.id.watchList);
watchList.setHasFixedSize(true);
listManager = new LinearLayoutManager(this);
watchList.setLayoutManager(listManager);
listAdapter = new WatchListAdapter(watchListArray);
listAdapter.setOnItemClickListener(new WatchListAdapter.OnItemClickListener() {
#Override
public void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
expandListItem(position, show, edit, delete, oLong, oShort);
}
});
watchList.setAdapter(listAdapter);
}
public void engage(Asset asset) {
int position = watchListArray.size();
String ticker = asset.getSymbol();
//Double.toString(asset.getCurrentPrice()) replaced with fixed value for testing
String price = "390.55";
//int indicator set to fixed value for testing
int indicator = R.drawable.ic_bull_indicator;
watchListArray.add(position, new WatchListItem(indicator, price, ticker));
listAdapter.notifyItemInserted(position);
}
public void expandListItem(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
if (edit.getVisibility() == View.GONE) {
show.setImageResource(R.drawable.ic_collapse);
oShort.animate().alpha(1f).setDuration(150);
oLong.animate().alpha(1f).setStartDelay(125).setDuration(150);
delete.animate().alpha(1f).setStartDelay(250).setDuration(150);
edit.animate().alpha(1f).setStartDelay(375).setDuration(150);
} else {
edit.animate().alpha(0f).setDuration(150);
delete.animate().alpha(0f).setStartDelay(125).setDuration(150);
oLong.animate().alpha(0f).setStartDelay(250).setDuration(150);
oShort.animate().alpha(0f).setStartDelay(375).setDuration(150);
show.setImageResource(R.drawable.ic_baseline_more_vert);
}
listAdapter.notifyItemChanged(position);
}
}
WatchListAdapter.java
public class WatchListAdapter extends RecyclerView.Adapter<WatchListAdapter.WatchListViewHolder> {
private ArrayList<WatchListItem> mWatchList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public static class WatchListViewHolder extends RecyclerView.ViewHolder {
public TextView mAssetSymbol;
public TextView mAssetPrice;
public ImageView mImageView;
public ImageView mShowOptions;
public FloatingActionButton mEditAsset;
public FloatingActionButton mDeleteAsset;
public FloatingActionButton mOpenLong;
public FloatingActionButton mOpenShort;
public WatchListViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
mAssetSymbol = itemView.findViewById(R.id.assetSymbol);
mAssetPrice = itemView.findViewById(R.id.assetPrice);
mImageView = itemView.findViewById(R.id.imageView);
mShowOptions = itemView.findViewById(R.id.showOptions);
mEditAsset = itemView.findViewById(R.id.editAsset);
mDeleteAsset = itemView.findViewById(R.id.deleteAsset);
mOpenLong = itemView.findViewById(R.id.openLong);
mOpenShort = itemView.findViewById(R.id.openShort);
}
}
public WatchListAdapter(ArrayList<WatchListItem> watchListArray) {
mWatchList = watchListArray;
}
#NonNull
#Override
public WatchListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new WatchListViewHolder(v, mListener);
}
#Override
public void onBindViewHolder(#NonNull WatchListViewHolder holder, int position) {
WatchListItem currentItem = mWatchList.get(position);
holder.mAssetSymbol.setText(currentItem.getAssetSymbol());
holder.mAssetPrice.setText(currentItem.getAssetPrice());
holder.mImageView.setImageResource(currentItem.getImageResource());
holder.mShowOptions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
ImageView show = holder.mShowOptions;
FloatingActionButton edit = holder.mEditAsset;
FloatingActionButton delete = holder.mDeleteAsset;
FloatingActionButton oLong = holder.mOpenLong;
FloatingActionButton oShort = holder.mOpenShort;
if (position != RecyclerView.NO_POSITION) {
listener.onShowOptionsClick(position, show, edit, delete, oLong, oShort);
}
}
}
});
}
#Override
public int getItemCount() {
return mWatchList.size();
}
}
Solved! Thank you to all who took the time to answer, especially to i_A_mok whose suggestion ultimately led to the fix. The code I had was perfectly sufficient; I only needed to add setVisibilty(View.VISIBLE) to each FAB before animating the alpha property. For some reason, I believed that by transitioning from alpha 0.0 to alpha 1.0 would automatically make the view visible, but alas this is not the case: visibility and alpha are two separate properties and need to be set independently.
I set up a Listview in Android Studio but need help with coding a OnItemClickListner.
I have tried the code, but doesn't seem to work.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.list_view);
ArrayList<Object> list = new ArrayList<>();
list.add(new LTCItem("30.06 Sign Violations","Submit A Complaint To Texas Attorney General",R.drawable.gavel));
list.add(new LTCItem("U.S. & Texas LawShield","Legal Defense For Self Defense",R.drawable.lawshield));
listView.setAdapter(new LTCAdapter(this, list));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
}
}
Below is my list_view file. Where in the file do block descendantFocusability as suggested? Do I put it under listView? Sorry I am learning .
<?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="match_parent"
android:alwaysDrawnWithCache="true"
android:background="#000000"
android:padding="8dp">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/itemListViewImgIcon"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="#+id/itemListViewImgIcon"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/itemListViewTxtTopicName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<TextView
android:id="#+id/itemListViewTxtTopicSubtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/itemListViewTxtTopicName"
</RelativeLayout>
Ok I added the adapter code which is a Java Class item. Where do I add the code here?
public class LTCAdapter extends BaseAdapter {
ArrayList<Object> list;
private static final int LTC_Item = 0;
private static final int HEADER = 1;
private LayoutInflater inflater;
public LTCAdapter(Context context, ArrayList<Object> list) {
this.list = list;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getItemViewType(int position) {
if (list.get(position) instanceof LTCItem) {
return LTC_Item;
} else {
return HEADER;
}
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return 1;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
switch (getItemViewType(i)) {
case LTC_Item:
view = inflater.inflate(R.layout.item_list_view, null);
break;
case HEADER:
view = inflater.inflate(R.layout.item_listview_header, null);
break;
}
}
switch (getItemViewType(i)) {
case LTC_Item:
ImageView image = (ImageView) view.findViewById(R.id.itemListViewImgIcon);
TextView name = (TextView) view.findViewById(R.id.itemListViewTxtTopicName);
TextView subtitle = (TextView) view.findViewById(R.id.itemListViewTxtTopicSubtitle);
image.setImageResource(((LTCItem) list.get(i)).getImage());
name.setText(((LTCItem) list.get(i)).getName());
subtitle.setText(((LTCItem) list.get(i)).getSubtitle());
break;
case HEADER:
TextView title = (TextView) view.findViewById(R.id.itemListViewHeader);
title.setText(((String) list.get(i)));
break;
}
return view;
}
}
Your ListView element doesn't have an ID, you should add android:id="#+id/list_view" to it in the XML file.
Here is an example:
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
As your list view contains focusable elements, you need to write this piece of code in parent layout in your list view item xml file
android:descendantFocusability="blocksDescendants"
I am programming a simple game in android and I encountered a problem with recyclerview. I need help please , tnx :)
I have an activity that create an arrayList and add my data to it then pass it to my recyclerview's adapter . In the adapter I write code that user can't select more than an image. Now the problem is there when I select first item and then scroll recyclerview I see that one of the last three items is selected. And this case happen for only fist line items and last three items too.
What can I do for that ?
My activity :
public class page_register extends AppCompatActivity {
Activity _A;
Context _C;
private RecyclerView recyclerView1, recyclerView2;
private AdsAdapter adapter1;
private Avatar2Adapter adapter2;
private ArrayList<Ads> adsArrayList;
TextView Tv1, Tv2;
EditText ET1, ET2;
Button BT_First, BT_Second;
ImageButton BT_Back;
ImageView img_first, img_second;
CardView cardView1, cardView2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page_register);
M_UI.SetOffKeyboard(this);
M_Font.Initial(this);
_A = this;
_C = this;
Initial();
adsArrayList = new ArrayList<>();
adsArrayList.add(new Ads(R.drawable.a1));
adsArrayList.add(new Ads(R.drawable.a2));
adsArrayList.add(new Ads(R.drawable.a3));
adsArrayList.add(new Ads(R.drawable.a4));
adsArrayList.add(new Ads(R.drawable.a5));
adsArrayList.add(new Ads(R.drawable.a6));
adsArrayList.add(new Ads(R.drawable.a7));
adsArrayList.add(new Ads(R.drawable.a8));
adsArrayList.add(new Ads(R.drawable.a9));
adsArrayList.add(new Ads(R.drawable.a10));
adsArrayList.add(new Ads(R.drawable.a11));
adsArrayList.add(new Ads(R.drawable.a12));
adsArrayList.add(new Ads(R.drawable.a13));
adsArrayList.add(new Ads(R.drawable.a14));
adsArrayList.add(new Ads(R.drawable.a15));
adsArrayList.add(new Ads(R.drawable.a16));
adsArrayList.add(new Ads(R.drawable.a17));
adsArrayList.add(new Ads(R.drawable.a18));
adsArrayList.add(new Ads(R.drawable.a19));
adsArrayList.add(new Ads(R.drawable.a20));
adsArrayList.add(new Ads(R.drawable.a21));
//--------------------------------------------
adapter1 = new AdsAdapter(adsArrayList, this, _C, _A, recyclerView1, 0);
adapter2 = new Avatar2Adapter(adsArrayList, this, _C, _A, recyclerView2, 0);
RecyclerView.LayoutManager layoutManager1 = new GridLayoutManager(_C, 3);
RecyclerView.LayoutManager layoutManager2 = new GridLayoutManager(_C, 3);
recyclerView1.setLayoutManager(layoutManager1);
recyclerView2.setLayoutManager(layoutManager2);
recyclerView1.setAdapter(adapter1);
recyclerView2.setAdapter(adapter2);
}
public void Initial() {
recyclerView1 = (RecyclerView) findViewById(R.id.recycler_view1);
recyclerView2 = (RecyclerView) findViewById(R.id.recycler_view2);
}
}
and my adapter :
public class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.AdsViewHolder> {
private ArrayList<Ads> dataList;
Context _C1;
Activity _A1;
RecyclerView r;
int SelectedPos = 0;
int id_prev;
CardView CV_Prev = null;
public AdsAdapter(ArrayList<Ads> dataList, FragmentActivity activity, Context _C, Activity _A, RecyclerView recyclerView, int i) {
this.dataList = dataList;
_A1 = _A;
_C1 = _C;
r = recyclerView;
}
#Override
public AdsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
final View view = layoutInflater.inflate(R.layout.avatars, parent, false);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View SelectCardView) {
try {
if (CV_Prev != null) {
CV_Prev.findViewById(R.id.img_select).setVisibility(View.INVISIBLE);
}
SelectCardView.findViewById(R.id.img_select).setVisibility(View.VISIBLE);
CV_Prev = (CardView) SelectCardView;
} catch (Exception e) {
Toast.makeText(_C1, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
return new AdsViewHolder(view);
}
#Override
public void onBindViewHolder(AdsViewHolder holder, int position) {
holder.CV_item.setTag(position);
//------------------------------------------------------------------
holder.img_avatar.setImageResource(dataList.get(position).getImage());
}
#Override
public int getItemCount() {
return dataList.size();
}
class AdsViewHolder extends RecyclerView.ViewHolder {
ImageView img_avatar;
CardView CV_item;
AdsViewHolder(View itemView) {
super(itemView);
//-----------------------------------------------------------
img_avatar = (ImageView) itemView.findViewById(R.id.img_avatar);
CV_item = (CardView) itemView.findViewById(R.id.cardView);
}
}
}
my view :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/cardView"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#00ffffff"
android:layoutDirection="ltr"
android:paddingLeft="5dp"
android:paddingRight="5dp"
card_view:cardBackgroundColor="#B2EBF2"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/img_avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00ffffff"
card_view:srcCompat="#drawable/a1" />
<ImageView
android:id="#+id/img_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:visibility="invisible"
card_view:srcCompat="#mipmap/ic_check_circle_black_48dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
my model :
public class Ads {
private int image;
public Ads(int image)
{
this.image = image;
}
public void setImage(int image) {this.image = image;}
public int getImage() {return image;}
}
below image shows my mean :
*** I tried to set id for each card and image and selecting them by their id but that didn't help too.
This happens because recycler view recycles the view in OnBindViewHolder.To solve this.
create a global variable to store the clicked position.
private mItemSelected=-1;
Then inside viewholder add the clickListener and onClick store the position of the clicked item.
class AdsViewHolder extends RecyclerView.ViewHolder {
ImageView img_avatar;
CardView CV_item;
AdsViewHolder(View itemView) {
super(itemView);
//-----------------------------------------------------------
img_avatar = (ImageView) itemView.findViewById(R.id.img_avatar);
CV_item = (CardView) itemView.findViewById(R.id.cardView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemSelected=getAdapterPosition();
notifyDataSetChanged();
}
});
}
}
And in inside OnBindViewHolder,
if(mItemSelected==position){
//code for image selected.
holder.CV_item.setVisibility(View.VISIBLE);
}else{
//code for image unselected.
holder.CV_item.setVisibility(View.INVISIBLE);
}
Also remove the click listener that has been added in the createViewholder instead add it inside the constructor of AdsViewHolder as added above.
EDIT:Check this updated code.Hope it helps you.
public class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.AdsViewHolder> {
private ArrayList<Ads> dataList;
Context _C1;
Activity _A1;
RecyclerView r;
int SelectedPos = 0;
int id_prev;
CardView CV_Prev = null;
private int mItemSelected=-1;
public AdsAdapter(ArrayList<Ads> dataList, FragmentActivity activity, Context _C, Activity _A, RecyclerView recyclerView, int i) {
this.dataList = dataList;
_A1 = _A;
_C1 = _C;
r = recyclerView;
}
#Override
public AdsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
final View view = layoutInflater.inflate(R.layout.avatars, parent, false);
return new AdsViewHolder(view);
}
#Override
public void onBindViewHolder(AdsViewHolder holder, int position) {
holder.CV_item.setTag(position);
holder.img_avatar.setImageResource(dataList.get(position).getImage());
if(mItemSelected==position){
//code for image selected.
holder.CV_item.setVisibility(View.VISIBLE);
}else{
//code for image unselected.
holder.CV_item.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
return dataList.size();
}
class AdsViewHolder extends RecyclerView.ViewHolder {
ImageView img_avatar;
CardView CV_item;
AdsViewHolder(View itemView) {
super(itemView);
//-----------------------------------------------------------
img_avatar = (ImageView) itemView.findViewById(R.id.img_avatar);
CV_item = (CardView) itemView.findViewById(R.id.cardView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemSelected=getAdapterPosition();
notifyDataSetChanged();
}
});
}
}
}
Replace this code
if (CV_Prev != null && CV_Prev.findViewById(R.id.img_select).getVisibility() == View.VISIBLE) {
CV_Prev.findViewById(R.id.img_select).setVisibility(View.INVISIBLE);
}
if(SelectCardView.findViewById(R.id.img_select).getVisibility() == View.INVISIBLE)
SelectCardView.findViewById(R.id.img_select).setVisibility(View.VISIBLE);
or you can create a global variable to store the clicked position and change its Visibility after second click
See if this helps: https://stackoverflow.com/a/46641850/4469112 I just explained how to properly set the on click listeners to recycler view's adapter and view holders. The important part is to set the listener to the view holder (and no directly to the view), and then to let the view holder to set itself as listener to the passed view. Remember the view is recycled and the content is binded to it at runtime (when you scroll in your case), that's why you're seeing the selection 'transferred' to the other items.
I am building a sudoku in android ,so how do i register all the textviews
for e.g :
button1=(Button)findViewByid(R.id.btn1)
Do i need to write 81 such statements to register every TextView
you can add the views in java code when app running.
you can write your textview's xml statement in an xml file alone, and then inflate it.
In this way, you don't need the view id, because you already have its reference.
grid.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
/>
MyActivity.java
ArrayList<TextView> list = new ArrayList<>();
for (int i = 0; i < 81; i++) {
TextView view = (TextView)LayoutInflater.from(ItemDragAndSwipeUseActivity.this).inflate(R.layout.grid, null);
list.add(view);
}
// then attach these views to the layout with addView()
you can use grid view with an adapter instead of text views
grid item
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:text="#string/country_name"
android:textColor="#color/accent_color"
android:gravity="center"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:background="#color/color_primary_dark"/>
</RelativeLayout>
Adapter class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private List<ItemObject> itemList;
private Context context;
public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
this.itemList = itemList;
this.context = context;
}
#Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
holder.textView.setText(itemList.get(position).getName());
}
#Override
public int getItemCount() {
return this.itemList.size();
}
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView textView;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView)itemView.findViewById(R.id.textView);
}
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Clicked Position = " + getPosition(), Toast.LENGTH_SHORT).show();
}
}
}
Activity class
public class MainActivity extends ActionBarActivity {
private GridLayoutManager lLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle(null);
Toolbar topToolBar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(topToolBar);
topToolBar.setLogo(R.drawable.logo);
topToolBar.setLogoDescription(getResources().getString(R.string.logo_desc));
List<ItemObject> rowListItem = getAllItemList();
lLayout = new GridLayoutManager(MainActivity.this, 4);
RecyclerView rView = (RecyclerView)findViewById(R.id.recycler_view);
rView.setHasFixedSize(true);
rView.setLayoutManager(lLayout);
RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(MainActivity.this, rowListItem);
rView.setAdapter(rcAdapter);
}
private List<ItemObject> getAllItemList(){
List<ItemObject> allItems = new ArrayList<ItemObject>();
allItems.add(new ItemObject("1");
allItems.add(new ItemObject("2");
allItems.add(new ItemObject("3");
return allItems;
}
}
You don't have to use IDs for this. You can just create a View (Container) in XML and fill it using a for loop completely without using IDs. You can access them afterwards via their index in the Container.
I hope this helped.
I have a bunch of values that get pulled from mysql database and then are displayed in cardview using RecyclerView. This works great.
I want to now implement onClick on each item that is pulled, can anyone please point me in the right direction? I'm looking at being able to click on a card and have another view open with the "image", "name" and "publisher" values that are pulled from mysql using json, problem is I don't know how to pass these values onto a new activity, especially the values being pulled from mysql.
Movies.java
public class Movies extends AppCompatActivity implements RecyclerView.OnScrollChangeListener {
//Creating a List of superheroes
private List<SuperHero> listSuperHeroes;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
//Volley Request Queue
private RequestQueue requestQueue;
//The request counter to send ?page=1, ?page=2 requests
private int requestCount = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.movies);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL_LIST));
recyclerView.setItemAnimator(new DefaultItemAnimator());
//Initializing our superheroes list
listSuperHeroes = new ArrayList<>();
requestQueue = Volley.newRequestQueue(this);
//Calling method to get data to fetch data
getData();
//Adding an scroll change listener to recyclerview
recyclerView.setOnScrollChangeListener(this);
//initializing our adapter
adapter = new CardAdapter(listSuperHeroes, this);
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
//Add back button to go back
#Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
}
public boolean onSupportNavigateUp(){
finish();
overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
return true;
}
//Request to get json from server we are passing an integer here
//This integer will used to specify the page number for the request ?page = requestcount
//This method would return a JsonArrayRequest that will be added to the request queue
private JsonArrayRequest getDataFromServer(int requestCount) {
//Initializing ProgressBar
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar1);
//Displaying Progressbar
progressBar.setVisibility(View.VISIBLE);
setProgressBarIndeterminateVisibility(true);
//JsonArrayRequest of volley
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigMovies.DATA_URL + String.valueOf(requestCount),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
//Calling method parseData to parse the json response
parseData(response);
//Hiding the progressbar
progressBar.setVisibility(View.GONE);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
//If an error occurs that means end of the list has reached
Toast.makeText(Movies.this, "No More Items Available", Toast.LENGTH_SHORT).show();
}
});
//Returning the request
return jsonArrayRequest;
}
//This method will get data from the web api
private void getData() {
//Adding the method to the queue by calling the method getDataFromServer
requestQueue.add(getDataFromServer(requestCount));
//Incrementing the request counter
requestCount++;
}
//This method will parse json data
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the superhero object
SuperHero superHero = new SuperHero();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
//Adding data to the superhero object
superHero.setImageUrl(json.getString(ConfigMovies.TAG_IMAGE_URL));
superHero.setName(json.getString(ConfigMovies.TAG_NAME));
superHero.setPublisher(json.getString(ConfigMovies.TAG_PUBLISHER));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the superhero object to the list
listSuperHeroes.add(superHero);
}
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
//This method would check that the recyclerview scroll has reached the bottom or not
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((GridLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
//Overriden method to detect scrolling
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//Ifscrolled at last then
if (isLastItemDisplaying(recyclerView)) {
//Calling the method getdata again
getData();
}
}
}
CardAdapter.java
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
//Imageloader to load image
private ImageLoader imageLoader;
private Context context;
//List to store all superheroes
List<SuperHero> superHeroes;
//Constructor of this class
public CardAdapter(List<SuperHero> superHeroes, Context context){
super();
//Getting all superheroes
this.superHeroes = superHeroes;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.superheroes_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
//Getting the particular item from the list
SuperHero superHero = superHeroes.get(position);
//Loading image from url
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(superHero.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.drawable.ic_blank, android.R.drawable.ic_dialog_alert));
//Showing data on the views
holder.imageView.setImageUrl(superHero.getImageUrl(), imageLoader);
holder.textViewName.setText(superHero.getName());
holder.textViewPublisher.setText(superHero.getPublisher());
}
#Override
public int getItemCount() {
return superHeroes.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
//Views
public NetworkImageView imageView;
public TextView textViewName;
public TextView textViewPublisher;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewPublisher = (TextView) itemView.findViewById(R.id.textViewPublisher);
}
}
}
Movies.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<ProgressBar
android:id="#+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</LinearLayout>
superheroes_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
android:layout_alignParentEnd="true"
android:layout_marginBottom="3dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/activity_horizontal_margin">
<com.android.volley.toolbox.NetworkImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageViewHero"
android:layout_gravity="center_horizontal" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow>
<TextView
android:text="Name"
android:paddingRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/textViewName"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</TableRow>
<TableRow>
<TextView
android:text="Publisher"
android:paddingRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/textViewPublisher"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
Let the ViewHolder class implement View.OnClickListener, then move it into CardAdapter class.
Call setOnClickListener(this) just after calling super inside ViewHolder constructor like that:
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewPublisher = (TextView) itemView.findViewById(R.id.textViewPublisher);
}
#Override
public void onClick(View view) {
// here you can get your item by calling getAdapterPosition();
SuperHero superHero = superHeroes.get(getAdapterPosition());
}