Recycler View Scrolling messed up - android

I am trying a heterogeneous Recycler view, following this tutorial. Heterogeneous Layouts All is working fine expect for the part where i scroll the Recycler view, the layouts aren't displayed properly. I have 2 layouts, one has text and other has images, on scrolling I am left with alot of blank space in the text section,giving a feel to the viewer that there was some image previously here.
I have checked links online but nothing solved the issue.Your help is needed and appreciated.
Here is my code
ComplexRecyclerViewAdapter
public class ComplexRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Object> items;
private final int STATUS = 0, IMAGE_STATUS = 1;
public ComplexRecyclerViewAdapter(List<Object> items) {
this.items = items;
}
#Override
public int getItemCount() {
return this.items.size();
}
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof ArrayFeedItem) {
return STATUS;
} else if (items.get(position) instanceof ArrayFeedItemWithImage) {
return IMAGE_STATUS;
}
return -1;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
if (viewType == STATUS){
View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false);
viewHolder = new ViewHolder1(v1);
}
else if(viewType ==IMAGE_STATUS){
View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false);
viewHolder = new ViewHolder2(v2);
}
else
viewHolder=null;
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder.getItemViewType() == STATUS )
{
ViewHolder1 vh1 = (ViewHolder1) viewHolder;
configureViewHolder1(vh1, position);
vh1.setIsRecyclable(false);
}
else
{
ViewHolder2 vh2 = (ViewHolder2) viewHolder;
configureViewHolder2(vh2, position);
vh2.setIsRecyclable(false);
}
}
private void configureViewHolder1(ViewHolder1 vh1, int position) {
ArrayFeedItem item = (ArrayFeedItem) items.get(position);
if (item != null) {
vh1.getHolderImage().setImageResource(item.img);
vh1.getHolderText().setText(item.txtname);
vh1.getStatusMsg().setText(item.StatusMsg);
vh1.getTimestamp().setText(item.Timestamp);
vh1.getUrl().setText(item.URL);
}
}
private void configureViewHolder2(ViewHolder2 vh2, int position) {
ArrayFeedItemWithImage item = (ArrayFeedItemWithImage) items.get(position);
if (item != null) {
vh2.getHolderImage().setImageResource(item.img);
vh2.getHolderText().setText(item.txtname);
vh2.getStatusMsg().setText(item.StatusMsg);
vh2.getTimestamp().setText(item.Timestamp);
vh2.getUrl().setText(item.URL);
vh2.getFeedImage().setImageResource(item.feedImage1);
}
}
}
This is how I am binding the adapter to the recycle view.
Home Activity
list=(RecyclerView) findViewById(R.id.list);
adapter =new ComplexRecyclerViewAdapter(items);
list.setNestedScrollingEnabled(false);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
list.setLayoutManager(mLayoutManager);
list.setItemAnimator(new DefaultItemAnimator());
list.setAdapter(adapter);
ViewHolder1
public class ViewHolder1 extends RecyclerView.ViewHolder {
private ImageView Image;
private TextView Text,Timestamp,StatusMsg,Url;
public ViewHolder1(View itemView) {
super(itemView);
Image=(ImageView) itemView.findViewById(R.id.img);
Text=(TextView)itemView.findViewById(R.id.txt);
Timestamp=(TextView)itemView.findViewById(R.id.timestamp);
StatusMsg=(TextView)itemView.findViewById(R.id.txtStatusMsg);
Url=(TextView)itemView.findViewById(R.id.txtUrl);
}
public ImageView getHolderImage() {
return Image;
}
public void setHolderImage(ImageView image) {
this.Image = image;
}
public TextView getHolderText() {
return Text;
}
public void setHolderText(TextView text) {
this.Text = text;
}
public TextView getTimestamp() {
return Timestamp;
}
public void setTimestamp(TextView timestamp) {
this.Timestamp = timestamp;
}
public TextView getStatusMsg() {
return StatusMsg;
}
public void setStatusMsg(TextView statusmsg) {
this.StatusMsg = statusmsg;
}
public TextView getUrl() {
return Url;
}
public void setUrl(TextView url) {
this.Url = url;
}
}
layout_viewholder1
<?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:background="#color/feed_bg"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_marginTop="#dimen/feed_item_margin"
android:background="#drawable/bg_parent_rounded_corner"
android:orientation="vertical"
android:paddingBottom="#dimen/feed_item_padding_top_bottom"
android:paddingTop="#dimen/feed_item_padding_top_bottom"
android:id="#+id/layout1"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="#dimen/feed_item_padding_left_right"
android:paddingRight="#dimen/feed_item_padding_left_right" >
<ImageView
android:id="#+id/img"
android:layout_width="#dimen/feed_item_profile_pic"
android:layout_height="#dimen/feed_item_profile_pic"
android:scaleType="fitCenter" >
</ImageView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="#dimen/feed_item_profile_info_padd" >
<TextView
android:id="#+id/txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold"
android:textColor="#color/black"/>
<TextView
android:id="#+id/timestamp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/timestamp"
android:textSize="#dimen/feed_item_timestamp"
/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="#+id/txtStatusMsg"
android:textColor="#color/black"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="#dimen/feed_item_status_pad_left_right"
android:paddingRight="#dimen/feed_item_status_pad_left_right"
android:paddingTop="#dimen/feed_item_status_pad_top" />
<TextView
android:id="#+id/txtUrl"
android:textColor="#color/black"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:linksClickable="true"
android:paddingBottom="10dp"
android:paddingLeft="#dimen/feed_item_status_pad_left_right"
android:paddingRight="#dimen/feed_item_status_pad_left_right"
android:textColorLink="#color/link" />
</LinearLayout>
</LinearLayout>
Thanks in advance.

I have faced this issue and realised that in my case I was toggling view visibility inside
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}
So what was happening is due to bad code on my part sometimes some of the views were getting completely hidden and hence were not getting removed or recylcled. This caused the randomness in the view. So if you have some code that changes the view visibility then remove that and test if the issue is still there.

pay attention to this point please!
if your app need remove item for any reason and you want to see removed item process in recyclerview so setISRecyclable to false is not good ,check it! so for every body wants to add this to adapter except(those that dont want to recycle some item for any reason) i have message:
please consider this point that in your adapter in onBindViewHolder for cases that need kind of toggle stuff Every call to onBindViewHolder must include either a load() call or a clear() call.
for example if you check the Boolean or 0-1 for setting some part of your RecyclerView item layout to gone or visible you should consider both of them in your If-Statement Block.
for example in this question i cant see else block inside configureViewHolder2 and 1 so messed up items happen maybe.
tnx to read patient reader

Related

Set Sticky Header and Items Layouts Recyclerview

I want to build a complex layout using recyclerview android. In the layout, I want to have a camera button to the top left fixed and a recyclerview wrapped around it with gallery images. I have checked flexbox layout manager for recyclerview but it doesn't seem to match my use-case.
I want the header to be non-repeating and not to scroll with other items vertically. Here's the layout for the header:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/shareLayout"
android:layout_width="185dp"
android:layout_height="135dp"
android:layout_below="#id/trendingToolbar"
android:background="#color/black">
<ImageView
android:id="#+id/cameraShareIV"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
app:srcCompat="#drawable/camera_white" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/cameraShareIV"
android:layout_centerHorizontal="true">
<TextView
android:id="#+id/infoTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="20dp"
android:gravity="center_horizontal"
android:text="#string/share_pic_video"
android:textColor="#android:color/white"
android:textSize="13sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/infoTxt"
android:layout_marginLeft="16dp"
android:text="#string/share_timeout_txt"
android:textColor="#color/colorPrimaryDark"
android:textSize="11sp"
android:textStyle="bold" />
</RelativeLayout>
and in my activity, here's the XML:
<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="base.android.com.thumbsapp.UI.Fragments.TrendingFragment">
<include layout="#layout/trending_toolbar"
android:id="#+id/trendingToolbar"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/trendingRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/trendingToolbar"/>
Previously, I had the header inside the activity XML but had no way to wrap a recyclerview around it. So, I have decide to use an adapter like below:
public class TrendingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = TrendingAdapter.class.getSimpleName();
private Context context;
private List<Trending> itemList;
private static final int HEADER = 0;
private static final int ITEMS = 1;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType){
case HEADER:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.trending_header, parent, false);
return new TrendingHeaderViewHolder(v);
case ITEMS:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.trending_items_layout, parent, false);
return new TrendingItemsViewHolder(v);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Trending tr = itemList.get(position);
if (holder instanceof TrendingHeaderViewHolder){
((TrendingHeaderViewHolder) holder).cameraShareIV.setOnClickListener( view -> {
// TODO: 4/2/2018 select image from gallery
});
} else if (holder instanceof TrendingItemsViewHolder){
// TODO: 4/2/2018 populate gallery items here with picasso
}
}
#Override
public int getItemCount() {
return itemList.size();
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
}
I'm confused how to make the header stick and also what to do for getItemViewType method.
Is this the right way to approach this?
Can anyone help out? Thanks.
For this lay out i suggest better option is use this header view
https://github.com/edubarr/header-decor
To make things simple i suggest you to look into this library
In your XML Place RecylerView into StickyHeaderView,choose horizontal or vertical orientation for your RecylerView
<tellh.com.stickyheaderview_rv.StickyHeaderView
android:id="#+id/stickyHeaderView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:scrollbars="vertical" />
</tellh.com.stickyheaderview_rv.StickyHeaderView>
Create data bean class for each item type in RecyclerView. They should extend DataBean. Override the method
public boolean shouldSticky() to decide whether the item view should be suspended on the top.
public class User extends DataBean {
private String login;
private int id;
private String avatar_url;
private boolean shouldSticky;
#Override
public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
return R.layout.item_user;
}
public void setShouldSticky(boolean shouldSticky) {
this.shouldSticky = shouldSticky;
}
// Decide whether the item view should be suspended on the top.
#Override
public boolean shouldSticky() {
return shouldSticky;
}
}
public class ItemHeader extends DataBean {
private String prefix;
#Override
public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
return R.layout.header;
}
#Override
public boolean shouldSticky() {
return true;
}
}
Create ViewBinder to bind different type views with specific data beans. As you see, provideViewHolder(View itemView) corresponds for onCreateViewHolder in RecyclerView, and bindView corresponds for onBindViewHolder in RecyclerView.
public class ItemHeaderViewBinder extends ViewBinder<ItemHeader, ItemHeaderViewBinder.ViewHolder> {
#Override
public ViewHolder provideViewHolder(View itemView) {
return new ViewHolder(itemView);
}
#Override
public void bindView(StickyHeaderViewAdapter adapter, ViewHolder holder, int position, ItemHeader entity) {
holder.tvPrefix.setText(entity.getPrefix());
}
#Override
public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
return R.layout.header;
}
static class ViewHolder extends ViewBinder.ViewHolder {
TextView tvPrefix;
public ViewHolder(View rootView) {
super(rootView);
this.tvPrefix = (TextView) rootView.findViewById(R.id.tv_prefix);
}
}
}
Instantiate StickyHeaderViewAdapter for RecyclerView and register ViewBinders for each item types.
rv = (RecyclerView) findViewById(R.id.recyclerView);
rv.setLayoutManager(new LinearLayoutManager(this));
List<DataBean> userList = new ArrayList<>();
adapter = new StickyHeaderViewAdapter(userList)
.RegisterItemType(new UserItemViewBinder())
.RegisterItemType(new ItemHeaderViewBinder());
rv.setAdapter(adapter);

Recycle view overlap items on scroll

Hello everyone i am facing a problem with recycle view.
im using a recycle view with swipe to change item position functionality where user can change the position of items by long press items.
all items comes dynamical with different types of views.
everything is working good but when im trying to scroll the view then items displaying in recycle view are overlap each other.
i search on google and got the solution that is override the method .
#Override
public int getItemViewType(int position) {
return position;
}
when im using this method in my adapter class then my swipe to change view functionality stop working.
can anyone explain my why it's happening..?
Here is whole adapter class
public class CreateEmailAdapter extends RecyclerView.Adapter<CreateEmailAdapter.MyViewHolder> implements ItemTouchHelperAdapter {
private static final String TAG = "CreateEmailAdapter";
public int position = 0;
public ArrayList<CampaignData> List;
private final OnStartDragListener mDragStartListener;
public CreateEmailAdapter(ArrayList<CampaignData> List, OnStartDragListener mDragStartListener) {
this.List = List;
this.mDragStartListener = mDragStartListener;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public ImageView imageView, imageView2, imageView3;
RelativeLayout MainListView;
public MyViewHolder(final View view) {
super(view);
parentLayout = (RelativeLayout) view.findViewById(R.id.parentLayout);
MainListView = (RelativeLayout) view.findViewById(R.id.MainListView);
title = (TextView) view.findViewById(R.id.MainTitle);
imageView2 = (ImageView) view.findViewById(R.id.imageViewPopup);
imageView3 = (ImageView) view.findViewById(R.id.movearrows);
imageView = (ImageView) view.findViewById(R.id.lytPatternColorDraw);
parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view1) {
position = getAdapterPosition();
HandleResponse(title.getText().toString(), view1, getAdapterPosition());
}
});
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row, parent, false);
return new MyViewHolder(mView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
CampaignData campaignData = this.List.get(position);
holder.parentLayout.setTag(campaignData);
String extraData = campaignData.getExtraData();
String MediaType = campaignData.getMediaType();
holder.MainListView.setVisibility(View.VISIBLE);
holder.title.setText(campaignData.getTitle());
holder.imageView.setImageResource(campaignData.getimage());
holder.imageView2.setTag(campaignData);
holder.imageView3.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
mDragStartListener.onStartDrag(holder);
}
return false;
}
});
}
#Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(List, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
return true;
}
#Override
public void onItemDismiss(int position) {
List.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
return List.size();
}
// #Override
// public int getItemViewType(int position) {
// return position;
// }
public int getPosition() {
return position;
}
}
XMl file list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff">
<RelativeLayout
android:id="#+id/MainListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/lytGrab"
android:visibility="visible">
<LinearLayout
android:id="#+id/lytPatternColor"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<ImageView
android:id="#+id/movearrows"
android:layout_width="18dp"
android:layout_height="36dp"
android:layout_marginRight="10dp"
android:background="#drawable/movearrows" />
<ImageView
android:id="#+id/lytPatternColorDraw"
android:layout_width="30dp"
android:layout_height="40dp"
android:orientation="vertical" />
</LinearLayout>
<TextView
android:id="#+id/MainTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:layout_toRightOf="#+id/lytPatternColor"
android:gravity="center_vertical"
android:padding="10dp"
android:singleLine="true"
android:text="Title Here "
android:textColor="#000"
android:textSize="16sp" />
</RelativeLayout>
<!--Copy images -->
<LinearLayout
android:id="#+id/lytGrab"
android:layout_width="30dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical">
<ImageView
android:id="#+id/imageViewPopup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:src="#drawable/three" />
</LinearLayout>
</RelativeLayout>

Xamarin RecyclerView with button on item other items are clicked

I have a Recyclerview with items who have some hidden extra description.
I put a button to reveal or hide the extra description.
It works ok, but the problem is that, If I press the first item, when I scroll I see some other items also revealed (for example if I press the first, it also reveals the 7, the 10, the 17 and the 20).
When I scroll back the revealed item is hidden again, that doesn't botter me, but it gives any info.
This is the code of the adapter
class ArticulosAdapter : RecyclerView.Adapter
{
// Event handler for item clicks:
public event EventHandler<int> ItemClick;
// Underlying data set
public List<Articulo> listado;
public ArticulosAdapter(List<Articulo> listadoArticulos)
{
listado = listadoArticulos;
}
// Create a new CardView (invoked by the layout manager):
public override ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.filaArticulo, parent, false);
// Create a ViewHolder to find and hold these view references, and
ArticuloViewHolder vh = new ArticuloViewHolder(itemView,OnClick);
vh.Arrow.Click += (o, e) =>
{
if (vh.Info.Visibility == ViewStates.Gone)
vh.Info.Visibility = ViewStates.Visible;
else
vh.Info.Visibility = ViewStates.Gone;
};
return vh;
}
// Fill in the contents
public override void OnBindViewHolder(ViewHolder holder, int position)
{
ArticuloViewHolder vh = holder as ArticuloViewHolder;
if (listado[position].imagen != null)
vh.Image.SetImageBitmap(listado[position].BitImage);
vh.Caption.Text = listado[position].nombre;
vh.Cantidad.Text = "DISPONIBLE :" + listado[position].cantidad;
}
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
// Return the number of photos available in the photo album:
public override int ItemCount
{
get { return listado.Count; }
}
public class ArticuloViewHolder : ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public TextView Cantidad { get; private set; }
public LinearLayout Info { get; private set; }
public ImageButton Arrow { get; private set; }
// Get references to the views defined in the CardView layout.
public ArticuloViewHolder(View itemView, Action<int> listener)
: base(itemView)
{
Image = itemView.FindViewById<ImageView>(Resource.Id.foto);
Caption = itemView.FindViewById<TextView>(Resource.Id.nombre);
Cantidad = itemView.FindViewById<TextView>(Resource.Id.cantidad);
Arrow = itemView.FindViewById<ImageButton>(Resource.Id.arrowButt);
Info = itemView.FindViewById<LinearLayout>(Resource.Id.infoLay);
itemView.Click += (sender, e) => listener(base.Position);
}
}
}
And this is the code of the row
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="150px"
android:layout_height="150px"
android:id="#+id/foto"
android:scaleType="centerCrop"
android:layout_gravity="center"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#333333"
android:text="Caption"
android:id="#+id/nombre"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="4dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/infoLay"
android:visibility="gone"
android:padding="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#333333"
android:text="Caption"
android:id="#+id/cantidad"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="4dp" />
</LinearLayout>
<ImageButton
android:id="#+id/arrowButt"
android:layout_width="match_parent"
android:src="#drawable/down"
android:layout_height="50dp"/>
</LinearLayout>
</android.support.v7.widget.CardView>
The other revealed items are the ones using the same (recycled) view holder and views.
You need to (re)set the visibility of the Info part in OnBindViewHolder().
In your case, as you don't mind if the item is hidden again when scrolling back, you can simply do something like :
public override void OnBindViewHolder(ViewHolder holder, int position)
{
...
vh.Info.Visibility = ViewStates.Gone
}

How to alternate the position of TextView in Android from adapter of RecyclerView?

trying to build a chat bot, but how to alternate the TextView in RecyclerView's adapter. See the screenshot below:
As you can see, all the responses are currently aligned to the start, I'd like to move the reply from one person to the other side from the adapter of the RecyclerView. Here is the code to the adapter:
CustomAdapter.class
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.FeedsViewHolder>
{
DataHolder d1 = new DataHolder();
public class FeedsViewHolder extends RecyclerView.ViewHolder
{
private TextView chat;
private Typeface face;
FeedsViewHolder(View itemView)
{
super(itemView);
chat = (TextView)itemView.findViewById(R.id.chatMessage);
face = Typeface.createFromAsset(itemView.getContext().getAssets(), "fonts/Roboto-Regular.ttf");
chat.setTypeface(face);
}
}
private static class DataHolder
{
List<Text> feeds;
}
CustomAdapter(List<Text> feeds)
{
this.d1.feeds = feeds;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public FeedsViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.chat_message, viewGroup, false);
FeedsViewHolder pvh = new FeedsViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(FeedsViewHolder feedViewHolder, int i)
{
if(d1.feeds.get(i).isMachineOrHuman())
{
feedViewHolder.chat.setBackgroundResource(R.drawable.user);
feedViewHolder.chat.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
}
else
feedViewHolder.chat.setBackgroundResource(R.drawable.ais);
feedViewHolder.chat.setText(d1.feeds.get(i).getMessage());
}
#Override
public int getItemCount()
{
if(d1.feeds!=null)
{
return d1.feeds.size();
}
else
{
return 0;
}
}
}
chat_message.xml
<TextView android:id="#+id/chatMessage"
android:layout_width="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android" />
Now, I made an alternative solution, that is by keeping two TextViews in chat_message.xml and changing the visibility settings of the unused TextView . But what I am looking for is whether is it possible to do it with a single TextView. Also, the background of the TextView is a 9-patch-image , which is assigned as a background resource from the adapter, so when I move the TextView it shouldn't also spoil the background. Any thoughts would be much appreciated. :)
#Override
public void onBindViewHolder(FeedsViewHolder feedViewHolder, int i)
{
if(d1.feeds.get(i).isMachineOrHuman())
{
feedViewHolder.chat.setBackgroundResource(R.drawable.user);
**feedViewHolder.chat.setGravity(Gravity.RIGHT);** // *Sent Message*
feedViewHolder.chat.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
}
else {
feedViewHolder.chat.setBackgroundResource(R.drawable.ais);
**feedViewHolder.chat.setGravity(Gravity.LEFT);** // *Receive Message*
feedViewHolder.chat.setText(d1.feeds.get(i).getMessage());
}
Create A child layout under the parent layout for The bubble(9-patch) and set the Gravity approrpriately as the TEXT(Message).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/message_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#drawable/message_bubble"
android:longClickable="true"
android:minHeight="40dp">
<TextView
android:id="#+id/message_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Put your message"
android:textColor="#color/black"
android:textColorLink="#color/black"
android:textSize="?attr/TextSizeBody"
android:visibility="visible" />
</LinearLayout>

Set image in cardview one by one from drawable

I am trying to add images in a cardview from drawable and text one by one using a recyclerview. say there are 10 images in my drawable i want to use only 5 of them. So how to do that ?
here is my cardview :
<?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"
android:id="#+id/placeCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
card_view:cardCornerRadius="#dimen/card_corner_radius">
<ImageView
android:id="#+id/placeImage"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop" />
<!-- Used for the ripple effect on touch -->
<LinearLayout
android:id="#+id/mainHolder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:orientation="horizontal" />
<LinearLayout
android:id="#+id/placeNameHolder"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_gravity="bottom"
android:orientation="horizontal">
<TextView
android:id="#+id/placeName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:paddingLeft="10dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#android:color/white" />
</LinearLayout>
</android.support.v7.widget.CardView>
here is my recyclerview adapter :
public class SubPlaceAdapter extends RecyclerView.Adapter<SubPlaceRecyclerViewHolder>{
String ImageUri;
#Override
public SubPlaceRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_places, null);
SubPlaceRecyclerViewHolder viewHolder = new SubPlaceRecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(SubPlaceRecyclerViewHolder holder, int position) {
// holder.subPlaceImage
}
#Override
public int getItemCount() {
return 0;
}
}
my view holder :
public class SubPlaceRecyclerViewHolder extends RecyclerView.ViewHolder {
protected ImageView subPlaceImage;
protected TextView subPlaceTitle;
public SubPlaceRecyclerViewHolder(View view) {
super(view);
this.subPlaceImage = (ImageView) view.findViewById(R.id.placeImage);
this.subPlaceTitle = (TextView) view.findViewById(R.id.placeName);
}
}
thanks for the help :)
Step 1. First create a Model
public class ImageModel {
int imageId;
String aboutText;
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
public String getAboutText() {
return aboutText;
}
public void setAboutText(String aboutText) {
this.aboutText = aboutText;
}
}
Step 2. Create a method which return arraylist of imageModel in your fragment/activity from where you set the adapter
private ArrayList<ImageModel> setImageData(){
ArrayList<ImageModel> projectList=new ArrayList<>();
ImageModel imageModel=new ImageModel();
imageModel.setImageId(R.mipmap.ic_star_fill);
imageModel.setAboutText("RandomText");
projectList.add(imageModel);
ImageModel imageModel1=new ProjectModel();
projectModel.setImageId(R.mipmap.ic_star_fill);
projectModel.setAboutText("RandomText");
projectList.add(projectModel);
return projectList;
}
Step 3. Create constructor in your adapter which takes ArrayList as an argument
public SubPlaceAdapter(ArrayList<ImageModel> mImageList) {
this.mActivity = mActivity;
this.mImageList = mImageList);
}
Step 4. Set your adapter in your fragment/ activity.
mSubPlaceAdapter = new SubPlaceAdapter(setImageData());
Step 5. Set your item in on BindView Holder
#Override
public void onBindViewHolder(SubPlaceRecyclerViewHolder holder, int position) {
ImageModel imageModel= mImageList.get(position)
holder.subPlaceImage.setImageResource(imageModel.getImageId());
}
#Override
public int getItemCount() {
return mImageList.size();
}
This code will give you the idea how to do it.Fill free to modify this answer.

Categories

Resources