why CardView causing slow down the scrolling process? - android

I was using listView without with the custom layout which is having
Linear layout as parent layout. Scrolling was fine, Then I need to
implement CardView for elevation and round corner, After implementation
list Scrolling become slow.Moreover it is also slowing down the
RecyclerView Process.
here is my xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/WhiteSmoke"
android:layout_margin="5dp"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="6dp">
<LinearLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/listviewback"
android:orientation="vertical"
android:padding="5dip">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/custom_listviewIV"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:src="#drawable/avatar2"
/>
<TextView
android:id="#+id/custom_listviewMainTv"
android:layout_width="180dip"
android:layout_height="45dip"
android:layout_marginLeft="2dip"
android:layout_toLeftOf="#+id/custom_listviewLinearLay"
android:layout_toRightOf="#+id/custom_listviewIV"
android:maxLines="2"
android:paddingTop="2dip"
android:text="Goverment "
android:textColor="#color/GreyDark"
android:textSize="15sp"
android:textStyle="bold"/>
<LinearLayout
android:id="#+id/custom_listviewLinearLay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_margin="2dip"
android:orientation="vertical">
<TextView
android:id="#+id/custom_listviewRating"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="right"
android:layout_marginBottom="2dp"
android:background="#drawable/tv_round"
android:backgroundTint="#color/primary_dark"
android:gravity="center"
android:text="4.2/5"
android:textColor="#color/white"
android:textSize="13sp" />
</LinearLayout>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginLeft="5dip"
android:background="#color/GreyLight" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dip"
android:orientation="vertical"
android:paddingLeft="10dip"
android:paddingTop="1dip"
android:paddingRight="10dip"
>
<TextView
android:id="#+id/custom_listviewFirstTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dip"
android:text="Fsc Pre Engineering1"
android:textColor="#color/greyligher"
android:textSize="13sp"
android:visibility="gone" />
<TextView
android:id="#+id/custom_listviewSecondTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fsc Pre Engineering2"
android:textColor="#color/greyligher"
android:textSize="13sp"
android:visibility="gone" />
<TextView
android:id="#+id/custom_listviewThirdTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fsc Pre Engineering3"
android:textColor="#color/greyligher"
android:textSize="13sp"
android:visibility="gone" />
<TextView
android:id="#+id/custom_listviewFourthTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="more+"
android:textColor="#color/black"
android:textSize="13sp"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
here is my adapter code
public class CustomAdaptor extends BaseAdapter {
private ArrayList<Data> myDataList;
private Context context;
LinearLayout linearLayout;
public CustomAdaptor(ArrayList<Data> mylist, Context context) {
this.myDataList = mylist;
this.context = context;
}
public int getCount() {
return myDataList.size();
}
public Object getItem(int position) {
return myDataList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = View.inflate(context, R.layout.custom_listview, null);
linearLayout= view.findViewById(R.id.layout);
TextView collegeName = view.findViewById(R.id.custom_listviewMainTv);
TextView rating = view.findViewById(R.id.custom_listviewRating);
ImageView country = view.findViewById(R.id.custom_listviewIV);
LinearLayout ll= view.findViewById(R.id.custom_listviewLinearLay);
TextView firstTv= view.findViewById(R.id.custom_listviewFirstTv);
TextView secondTv= view.findViewById(R.id.custom_listviewSecondTv);
TextView thirdTv= view.findViewById(R.id.custom_listviewThirdTv);
TextView fourthTv= view.findViewById(R.id.custom_listviewFourthTv);
collegeName.setText(myDataList.get(position).getName());
rating.setText("" + myDataList.get(position).getRating());
Double n=0.0;
if (n==myDataList.get(position).getRating()) {
ll.setVisibility(View.GONE);
}
if(!myDataList.get(position).getCourseList().isEmpty()) {
if (!myDataList.get(position).getCourseList().get(0).lst.get(0).getCourseName().equals("")) {
firstTv.setVisibility(View.VISIBLE);
firstTv.setText(myDataList.get(position).getCourseList().get(0).lst.get(0).getCourseName());
}
if (myDataList.get(position).getCourseList().get(0).lst.size()>1) {
if (!myDataList.get(position).getCourseList().get(0).lst.get(1).getCourseName().equals("")) {
secondTv.setVisibility(View.VISIBLE);
secondTv.setText(myDataList.get(position).getCourseList().get(0).lst.get(1).getCourseName());
}
}
if (myDataList.get(position).getCourseList().get(0).lst.size()>2) {
if (!myDataList.get(position).getCourseList().get(0).lst.get(2).getCourseName().equals("")) {
thirdTv.setVisibility(View.VISIBLE);
thirdTv.setText(myDataList.get(position).getCourseList().get(0).lst.get(2).getCourseName());
}
}
if (myDataList.get(position).getCourseList().size()>1) {
fourthTv.setVisibility(View.VISIBLE);
fourthTv.setText("+More");
}else if(myDataList.get(position).getCourseList().get(0).lst.size()>3) {
fourthTv.setVisibility(View.VISIBLE);
fourthTv.setText("+More");
}
String img = "" + myDataList.get(position).getImage();
img = img.replaceAll(" ", "%20");
Glide.with(context).load(img).into(country);
view.setTag(myDataList.get(position).getId());
}
else {
linearLayout.setVisibility(View.GONE);
}
return view;
}
}

Try to minimize your view hierarchy and reduce complex operations from binding.

Cardview is probably just the "breaking point" for how much graphic content that cna be used in an unoptimized way without lagging. As mentioned in some comments you should be using a ViewHolder, here is a simple example of using a viewholder:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_entry, null);
holder = new ViewHolder();
holder.nameTextView = (TextView) convertView.findViewById(R.id.person_name);
holder.surnameTextView = (TextView) convertView.findViewById(R.id.person_surname);
holder.personImageView = (ImageView) convertView.findViewById(R.id.person_image);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
Person person = getItem(position);
holder.nameTextView.setText(person.getName());
holder.surnameTextView.setText(person.getSurname());
//holder.personImageView.setImageBitmap(person.getImage());
return convertView;
}
you can read more about it here
Additionally you should be using RecyclerView and not ListView, to optimize performance.

You can do as following:
Use latest version of RecyclerView support library
implementation 'com.android.support:recyclerview-v7:28.0.0'
Replace a complex layout
(nested views, RelativeLayout) with the new optimized ConstraintLayout. Activate it in Android Studio: Go to SDK Manager -> SDK Tools tab -> Support Repository -> check ConstraintLayout for Android & Solver for ConstraintLayout. Add to the dependencies:
compile 'com.android.support.constraint:constraint-layout:2.0.0-alpha4'
If possible, make all elements of the RecyclerView with the same height. And add:
recyclerView.setHasFixedSize(true);
Use the default RecyclerView drawing cache methods and tweak them according to your case. You don't need third party library to do so:
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
If you use many images, make sure their size and compression are optimal. Scaling images may also affect the performance. There are two sides of the problem - the source image used and the decoded Bitmap. The following example gives you a hint how to decode аn image, downloaded from the web:
InputStream is = (InputStream) url.getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap image = BitmapFactory.decodeStream(is, null, options);
Reference : this

Related

ImageView is small after rotation of device

After rotation of device -> Image (id=list_image2) remains small like it was at portrate mode
Seems it is because I change count of Columns gridView.setNumColumns(3);, but viewholder still contains previous imageview with previous width and height, also I tryed to make gridView.invalidate(); in onConfigurationChanged...but no result
added to activity in Manifest
android:configChanges="keyboardHidden|orientation|screenSize"
Here is item_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_row_root"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingLeft="1dip"
android:paddingRight="1dip"
<ImageView
android:id="#+id/list_image2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:minWidth="#dimen/grid_item_width"
android:minHeight="#dimen/grid_item_height"
android:src="#drawable/ic_action_cloud"
android:scaleType="fitXY"
/>
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:layout_alignBottom="#+id/list_image2"
android:layout_alignTop="#+id/list_image2"
android:layout_centerHorizontal="true" />
<RelativeLayout
android:id="#+id/likes_RelativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/field_likes"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_alignBottom="#+id/list_image2"
android:layout_alignRight="#+id/list_image2"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp" >
<TextView
android:id="#+id/likes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:text="265465" />
<ImageView
android:id="#+id/btn_favoutites"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="#+id/likes"
android:src="#drawable/btn_rating_star_on_normal_holo_dark"
android:text="Button" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/btn_RelativeLayout"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignBottom="#+id/likes_RelativeLayout"
android:layout_alignLeft="#+id/likes_RelativeLayout"
android:layout_alignRight="#+id/likes_RelativeLayout"
android:layout_alignTop="#+id/likes_RelativeLayout"
android:background="#drawable/field_like_clickable_style" >
</RelativeLayout>
Here is my adapter:
publ
ic class LazyAdapter2 extends BaseAdapter{
public LazyAdapter2(Context context, ArrayList<WallImage> d) {
mContext = context;
data=d;
inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.resetViewBeforeLoading(true)
.imageScaleType(ImageScaleType.EXACTLY)// default
.build();
}
public View getView( int position, View convertView, ViewGroup parent) {
final ViewHolderItem viewHolder;
if(convertView==null)
{
convertView = inflater.inflate(R.layout.item_grid, null);
viewHolder = new ViewHolderItem();
viewHolder.thumb_image=(ImageView)convertView.findViewById(R.id.list_image2); // thumb image
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolderItem) convertView.getTag();
}
WallImage imageObject = data.get(position);
viewHolder.likes.setText(imageObject.views);
imageLoader.displayImage(imageObject.preview, viewHolder.thumb_image, options);
return convertView;
}
}
Not just invalidate but how about like this with Handler.post()?:
new Handler(getMainLooper()).post(new Runnable() {
#Override
public void run() {
gridView.invalidate();
}
});
Maybe this is due to the use of convertView in your getView method?
It keeps the original layout and don't recreate it when orientation change.
You could add to your ViewHolderItem class a boolean member that indicates the screen orientation.
And when you recycle the view, you test your viewHolder orientation. If it's different from the current screen orientation, don't recycle it.
Solved by changing of item_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_row_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingLeft="1dip"
android:paddingRight="1dip"
>
<ImageView
android:id="#+id/list_image2"
android:layout_width="match_parent"
android:layout_height="#dimen/grid_item_height"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:scaleType="centerCrop"
android:src="#android:color/transparent"
/>
after doing of ImageView android:layout_height="#dimen/grid_item_height" => after rotation of screen image size remains constant, but to resize imege in ImageView I use android:scaleType="centerCrop" after that image is slighly cutted , but problem is solved
Try imageScaleType(ImageScaleType.IN_SAMPLE_INT)
and
imageLoader.displayImage(imageObject.preview, viewHolder.thumb_image, options);
viewHolder.thumb_image.setScaleType(ImageView.ScaleType.FILL_XY);

Items in a Listview don't look like my item layout

I'm building an app for a news website, I have created a ListView and a layout for each item, which has quite a bit of white space, but on the list view all the white space is removed.
Here's what I mean: http://imgur.com/a/mLuuE
This is an item layout:
<?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="175dp"
android:gravity="center"
android:layout_weight="0"
android:id="#+id/article_layout"
android:background="#drawable/gradientdemo">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center|bottom"
android:orientation="vertical"
android:paddingLeft="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="Titolo dell'articolo"
android:textSize="#dimen/abc_text_size_headline_material"
android:layout_gravity="left"
android:id="#+id/article_title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="3/9/16 - Autore"
android:layout_gravity="left"
android:id="#+id/article_info" />
</LinearLayout>
</LinearLayout>
This is my custom adapter:
public class ArticleAdapter extends ArrayAdapter<Article> {
public ArticleAdapter(Context context, int textViewResourceId){
super(context, textViewResourceId);
}
public ArticleAdapter(Context context, int resource, List<Article> items ){
super(context, resource, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.article_item, null);
}
Article article = (Article) getItem(position);
TextView title = (TextView) v.findViewById(R.id.article_title);
TextView info = (TextView) v.findViewById(R.id.article_info);
if( title != null ) {
title.setText( article.getTitle() );
}
if( info != null ) {
info.setText( article.getAuthor() );
}
return v;
}
}
Hope it's readable, I'm kind of new to android development.
Your cell's LineaerLayout:
android:layout_height="0dp"
android:layout_weight="1"
change to:
android:layout_height="wrap_content"
you don't need layout_weight
Delete the android:layout_weight="1" and add a correct height, e.g. android:layout_height="60dp":
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center|bottom"
android:orientation="vertical"
android:paddingLeft="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="Titolo dell'articolo"
android:textSize="#dimen/abc_text_size_headline_material"
android:layout_gravity="left"
android:id="#+id/article_title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="3/9/16 - Autore"
android:layout_gravity="left"
android:id="#+id/article_info" />
</LinearLayout>
in the linearLayout use wrapcontent, erase layout_weigth and add weigthsum=1
Then in textViews change height to 0dp and add to each one layout_weight=0.5
I think this will work
I fixed this by changing this line in the adapter
v = vi.inflate(R.layout.article_item, null);
to this one:
v = vi.inflate(R.layout.article_item, parent, false);

RecyclerView extra empty gap between items

1.i just implemented some recyclerviews, some of their items have extra empty space. this space sometimes disappears after some scrolling. i have tried every way you could think! i have changed heights to wrap content but still issue exists!
here is the screenshot:
Recyclerview empty space
here is item xml:
<android.support.v7.widget.CardView
android:id="#+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:gravity="center"
android:orientation="horizontal"
android:adjustViewBounds="true"
android:padding="8dp"
android:layout_margin="6dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/banner_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/no_image_banner" />
<TextView
android:id="#+id/txtHey"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="center"
android:maxLength="20"
android:text="sadas"
android:textColor="#4d4a46"
android:textSize="11dp"
android:textStyle="bold" />
<TextView
android:id="#+id/txtHi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:gravity="center"
android:text="sadas"
android:textColor="#999999"
android:textSize="9dp" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_vertical">
<TextView
android:id="#+id/txtPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="sadas"
android:textColor="#888888"
android:textSize="9dp" />
<LinearLayout
android:id="#+id/price_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="#888888"
android:orientation="horizontal" />
</FrameLayout>
<TextView
android:id="#+id/txtFinalPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="sadas"
android:textColor="#3dc24d"
android:textSize="9dp" />
<TextView
android:id="#+id/txtHello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="hey"
android:textSize="9dp"
android:visibility="gone" />
</LinearLayout>
</android.support.v7.widget.CardView>
main page xml:
<android.support.design.widget.AppBarLayout
android:id="#+id/topBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<include
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/product_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
>
</android.support.v7.widget.RecyclerView>
<TextView
android:id="#+id/request_results"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="21dp"
android:textStyle="bold" />
</RelativeLayout>
second question is i used some recyclerviews inside a nested scroll view to prevent scrolling issues. everything is good but in lower versions of android like kitkat i have problem with scrolling(cause nested wont work on sdk<21 ) . i could use a normal scrollview that works well on both versions but normal scroll view doesnt work with coordinator layout and so appbar layout hiding behaviour wont work!
can you help me with these problems please?
here is the adapter class:
private ArrayList<Struct> structs;
OnItemListener onItemListener;
private boolean isGrid;
private int Tab;
public Adapter_Recycler(ArrayList<Struct> structs, OnItemListener onItemListener, int Tab, boolean isGrid) {
this.structs = structs;
this.onItemListener = onItemListener;
this.Tab = Tab;
this.isGrid = isGrid;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = null;
if (Tab == 2) {
view = inflater.inflate(R.layout.item_product_color, parent, false);
}
if (Tab == 1 && isGrid == false) {
view = inflater.inflate(R.layout.item_product_list, parent, false);
}
if (Tab == 1 && isGrid) {
view = inflater.inflate(R.layout.item_product_list, parent, false);
}
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
if (Tab == 2) {
holder.txtHey.setText(structs.get(position).hey);
holder.txtPrice.setText(structs.get(position).hi);
holder.txtHi.setVisibility(View.GONE);
holder.PriceCancel.setVisibility(View.GONE);
holder.txtFinalPrice.setVisibility(View.GONE);
holder.txtHey.setTypeface(Activity_Main.SANS);
holder.txtPrice.setTypeface(Activity_Main.SANS);
Glide
.with(Activity_Main.CONTEXT)
.load(structs.get(position).image)
.placeholder(R.drawable.background_card)
.fitCenter()
.into(holder.banner_image);
}
if (Tab == 1) {
holder.txtHey.setText(structs.get(position).hey);
holder.txtHi.setText(structs.get(position).hi);
holder.txtPrice.setText(structs.get(position).price);
holder.txtFinalPrice.setText(structs.get(position).final_price);
if (holder.txtFinalPrice.getText().toString() == "") {
holder.PriceCancel.setVisibility(View.GONE);
} else {
holder.PriceCancel.setVisibility(View.VISIBLE);
}
holder.txtHey.setTypeface(Activity_Main.SANS);
holder.txtHi.setTypeface(Activity_Main.SANS);
holder.txtPrice.setTypeface(Activity_Main.SANS);
holder.txtFinalPrice.setTypeface(Activity_Main.SANS);
Glide
.with(Activity_Main.CONTEXT)
.load(structs.get(position).image)
.placeholder(R.drawable.background_card)
.fitCenter()
.into(holder.banner_image);
}
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (onItemListener != null) {
onItemListener.onItemSelect(position);
}
}
});
holder.txtHello.setText(structs.get(position).hello);
holder.txtHello.setTypeface(Activity_Main.SANS);
}
#Override
public int getItemCount() {
return structs.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
CardView linearLayout;
ImageView banner_image;
TextView txtHey;
TextView txtHi;
TextView txtHello;
TextView txtPrice;
TextView txtFinalPrice;
LinearLayout PriceCancel;
public ViewHolder(View itemView) {
super(itemView);
linearLayout = (CardView) itemView.findViewById(R.id.btn);
banner_image = (ImageView) itemView.findViewById(R.id.banner_image);
txtHey = (TextView) itemView.findViewById(R.id.txtHey);
txtHi = (TextView) itemView.findViewById(R.id.txtHi);
txtHello = (TextView) itemView.findViewById(R.id.txtHello);
txtPrice = (TextView) itemView.findViewById(R.id.txtPrice);
txtFinalPrice = (TextView) itemView.findViewById(R.id.txtFinalPrice);
PriceCancel = (LinearLayout) itemView.findViewById(R.id.price_cancel);
}
}
}
UPDATE:
the place holder aspect ratio must not be much different from the images aspect ratio. they should be the same.
If possible then provide adapter class because may be some issue with onCreateViewHolder with LayoutInflater.
I finally figured out what the problem was!
that extra space was because of
" .placeholder(R.drawable.background_card) " !
problem solved after removing the placeholder.
ofcourse issue is with the image! not placeholder.

Create custom ListView with shadow

How could I create custom ListView like shown in this picture. I know I can make this happen with help of ScrollView and Layouts, but I need to do as a ListView.
Each listview item go over each other.
This may help you
List view with custom view items with partially overlaps (Android)
I have this code like your Requirement. List may overlap by reducing the dividerheight to minus value
<?xml version="1.0" encoding="utf-8"?>
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#b5b5b5"
android:dividerHeight="-5dp"
android:listSelector="#drawable/list_selector" />
Then add background color to adapter according to the position.
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
TextView title = (TextView)vi.findViewById(R.id.title); // title
TextView artist = (TextView)vi.findViewById(R.id.artist); // artist name
TextView duration = (TextView)vi.findViewById(R.id.duration); // duration
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image
HashMap<String, String> song = new HashMap<String, String>();
if(position % 2 ==0){
vi.setBackgroundResource(R.drawable.listselector_1);
}else if(position % 3 ==0){
vi.setBackgroundResource(R.drawable.listselector_2);
}else{
vi.setBackgroundResource(R.drawable.listselector_3);
}
song = data.get(position);
// Setting all values in listview
title.setText(song.get(CustomizedListView.KEY_TITLE));
artist.setText(song.get(CustomizedListView.KEY_ARTIST));
duration.setText(song.get(CustomizedListView.KEY_DURATION));
imageLoader.DisplayImage(song.get(CustomizedListView.KEY_THUMB_URL), thumb_image);
return vi;
}
Otherwise you can use listselector images also as your requirement
Thank you guys for trying help me to solve this issue. I look every answer here and finally get i want. I think it will be better I put my code here so maybe someone it will be helpful. The only difference is that my created listview has also shadow in it.
Here is the code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my_font="http://schemas.android.com/apk/res/com.Helix.android.SmartBonus"
android:orientation="vertical"
android:id="#+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
>
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/shadow_bg"
android:visibility="visible"/>
<RelativeLayout
android:id="#+id/secondLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#drawable/drop_shadow"
android:layout_below="#id/imageview">
<ImageView
android:id="#+id/companyImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/secret_logo_small"
android:layout_marginRight="10dp"/>
<TextView
android:id="#+id/companyDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/companyImageView"
android:textColor="#android:color/white"
android:layout_marginTop="7dp"
my_font:ttf_name="300"
android:text="Салон кросаты"/>
<TextView
android:id="#+id/companyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/companyImageView"
android:layout_below="#id/companyDescription"
android:textColor="#android:color/white"
my_font:ttf_name="300"
android:text="Secret"/>
<TextView
android:id="#+id/companyPercentText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:layout_marginTop="7dp"
android:textSize="19sp"
android:layout_marginRight="1dp"
android:layout_toLeftOf="#+id/companyPercent"
my_font:ttf_name="700"
android:text="-20"/>
<TextView
android:id="#id/companyPercent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textColor="#android:color/white"
android:layout_marginTop="7dp"
android:textSize="12sp"
my_font:ttf_name="300"
android:text="%"/>
<ImageView
android:id="#+id/companyPercentImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/companyPercent"
android:layout_marginTop="7dp"
android:textColor="#android:color/white"
android:src="#drawable/percentage_devider"/>
<TextView
android:id="#+id/companyDistance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/companyPercentImage"
android:textSize="16dp"
android:textColor="#A57F1C"
my_font:ttf_name="300"
android:text="7m"/>
<LinearLayout
android:id="#+id/checkingButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/companyDistance"
android:layout_marginTop="10dp"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:focusable="false"
android:background="#drawable/green_button_bg"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="16dp"
android:textColor="#android:color/white"
my_font:ttf_name="300"
android:text="Check-in"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="16dp"
android:layout_marginLeft="10dp"
android:textColor="#color/checkin_point_color"
android:layout_weight="1"
my_font:ttf_name="300"
android:text="#string/ten_point"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/slak"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
adapter.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
final Discount discount = getItem(i);
Discount prev_discount = null;
if (i > 0){
prev_discount = getItem(i-1);
}
if (view == null){
final LayoutInflater li = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.discount_data_item, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.logo = (ImageView)view.findViewById(R.id.companyImageView);
viewHolder.name = (SmartBonus_TextView)view.findViewById(R.id.companyName);
viewHolder.description = (SmartBonus_TextView)view.findViewById(R.id.companyDescription);
viewHolder.percent = (SmartBonus_TextView)view.findViewById(R.id.companyPercentText);
viewHolder.distance = (SmartBonus_TextView)view.findViewById(R.id.companyDistance);
viewHolder.mainLayout = (RelativeLayout)view.findViewById(R.id.mainLayout);
viewHolder.secondLayaout = (RelativeLayout)view.findViewById(R.id.secondLayout);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
if (i == 0){
viewHolder.mainLayout.setBackgroundColor(android.R.color.transparent);
setRoundedBackground(viewHolder.secondLayaout, Color.parseColor(discount.getBackgroundColor()));
} else {
viewHolder.mainLayout.setBackgroundColor(Color.parseColor(prev_discount.getBackgroundColor()));
setRoundedBackground(viewHolder.secondLayaout, Color.parseColor(discount.getBackgroundColor()));
}
return view;
}
private void setRoundedBackground(View view,int color){
final GradientDrawable gradientDrawable = (GradientDrawable) view.getBackground().mutate();
gradientDrawable.setColor(color);
gradientDrawable.invalidateSelf();
}
Here is the result
You should override getView method.
Sample code:
View getView(int position, View convertView, ViewGroup parent){
Object data = getItem(positon);
//usually data object should have type property
if(data.type == TYPE1){
return getLayoutInflater().inflate(R.layout.custom_xml1, null);
}else (data.type == TYPE2){
return getLayoutInflater().inflate(R.layout.custom_xml2, null);
}else{
return getLayoutInflater().inflate(R.layout.custom_xml, null);
}
};
Note:You should reuse convertView object for performance.
Ok, As I have sort of time I manage to write few steps to achieve your task.
1. Make Custom drawable using xml in drawable folder with top corners have radius..
2. Now in your Listview attributes just define negative divider height
Like, android:dividerHeight="-20dp"
3. Set the Custom Drawable as a background of List row in getView().
Also its nice if you able to set color to drawable at dynamically for list row. (In getView() of Custom Adapter).
This what I have achieved from above steps:

android: how to change property of layout_gravity of a row_item in a listview

I'm trying to implement a chat bubbles that can appear to the left or the right.
I read a lot of answers already published here but i didn't manage to get any of them working for me, maybe i'm missing something.
if i change the layout_gravity of the linearLayout in the row_item xml from left to right manually and then look at the graphical layout i can see that it works as i wanted.
the problem is that i'm unable to control this property.
as i understand the problem is connect to the fact that the LayoutParams that exist are of the listview.LayoutParams, and if i try to get the LayoutParams to an listview.LayoutParams object it works. but that is not what i'm trying to achieve.
here's the code:
the activity xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="MergeRootFrame" >
<ListView
android:id="#+id/listViewMessages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.98" >
</ListView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.02"
android:background="#D3D3D3"
android:orientation="horizontal" >
<EditText
android:id="#+id/editTextMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/imageButtonSend"
android:ems="10"
android:hint="#string/textFieldMessage"
android:textSize="14sp"
android:visibility="visible" >
<requestFocus />
</EditText>
<ImageButton
android:id="#+id/imageButtonSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="14dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="#string/imageButtonSendNow_contentDescription"
android:src="#drawable/ic_action_send_now"
android:onClick="onClick" />
</RelativeLayout>
</LinearLayout>
the row_item 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:id="#+id/singleMessageContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:orientation="horizontal"
android:padding="6dp" >
<TextView
android:id="#+id/textViewMessage"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_weight="0.85"
android:layout_marginBottom="2dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:text="Message"
android:textSize="16sp"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/TextViewTime"
android:layout_width="wrap_content"
android:layout_height="14dp"
android:layout_weight="0.1"
android:layout_gravity="bottom"
android:layout_marginLeft="22dp"
android:gravity="center_vertical"
android:text="Time"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<ImageView
android:id="#+id/imageViewSuccess"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_weight="0.05"
android:layout_gravity="bottom"
android:contentDescription="successIcon"
android:src="#drawable/ic_action_accept"
tools:ignore="HardcodedText" />
</LinearLayout>
the adapter code:
public class ConversationAdapter extends ArrayAdapter<Message> {
private final Context context;
static class ViewHolder {
public TextView message;
public TextView time;
public ImageView success;
public LinearLayout singleMessageContainer;
}
public ConversationAdapter(Context context, ArrayList<Message> values) {
super(context, R.layout.conversation_list_item, values);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.conversation_list_item, parent,false);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.message = (TextView) rowView.findViewById(R.id.textViewMessage);
viewHolder.time = (TextView) rowView.findViewById(R.id.TextViewTime);
viewHolder.success = (ImageView) rowView.findViewById(R.id.imageViewSuccess);
viewHolder.singleMessageContainer = (LinearLayout) rowView.findViewById(R.id.singleMessageContainer);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.message.setText(getItem(position).getMessage());
holder.time.setText(getItem(position).getUniversalTimeString());
holder.success.setImageResource(R.drawable.ic_action_accept);
boolean isMine = (getItem(position).getSender() == 0);
holder.singleMessageContainer.setBackgroundResource(
isMine ? R.drawable.bubble_yellow : R.drawable.bubble_green);
// This part doesn't work
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
holder.singleMessageContainer.getLayoutParams();
params.gravity=(isMine ? Gravity.LEFT : Gravity.RIGHT);
holder.singleMessageContainer.setLayoutParams(params);
return rowView;
}
}
Solution
I went on reading about gravity and layout_gravity and encountered a more detail information that helped me to solve this problem.
In few answers to questions over here, there is a solution to use warpper layout but the important things to notice weren't written.
first thing to know is that is you set linear layout as horizontal you will not be able to use the gravity property as left or right only top or bottom
so the outer container has to be vertical and the innner warpper has to be horizontal for displaying the message and other data one after the other in a line.
and then you can use the method setGravity(Gravity.LEFT) or setGravity(Gravity.RIGHT) of the outer container to properly align the inner warpper to the left or the right.
you need to pay attention also to the properties of fill_parent and wrap_content
here the updated code:
the row_item 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:id="#+id/singleMessageContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:orientation="vertical"
android:padding="6dp" >
<LinearLayout
android:id="#+id/warpper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/textViewMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginBottom="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="2dp"
android:text="Message"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/TextViewTime"
android:layout_width="wrap_content"
android:layout_height="14dp"
android:layout_gravity="bottom"
android:text="Time"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<ImageView
android:id="#+id/imageViewSuccess"
android:layout_width="wrap_content"
android:layout_height="12dp"
android:layout_gravity="bottom"
android:contentDescription="successIcon"
android:src="#drawable/ic_action_accept"
tools:ignore="HardcodedText" />
</LinearLayout>
</LinearLayout>
and the updated adpater code:
public class ConversationAdapter extends ArrayAdapter<Message> {
private final Context context;
static class ViewHolder {
public TextView message;
public TextView time;
public ImageView success;
public LinearLayout singleMessageContainer;
// Added
public LinearLayout warpper;
}
public ConversationAdapter(Context context, ArrayList<Message> values) {
super(context, R.layout.conversation_list_item, values);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.conversation_list_item, parent,false);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.message = (TextView) rowView.findViewById(R.id.textViewMessage);
viewHolder.time = (TextView) rowView.findViewById(R.id.TextViewTime);
viewHolder.success = (ImageView) rowView.findViewById(R.id.imageViewSuccess);
viewHolder.singleMessageContainer = (LinearLayout) rowView.findViewById(R.id.singleMessageContainer);
// Added
viewHolder.warpper = (LinearLayout) rowView.findViewById(R.id.warpper);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.message.setText(getItem(position).getMessage());
holder.time.setText(getItem(position).getUniversalTimeString());
holder.success.setImageResource(R.drawable.ic_action_accept);
boolean isMine = (getItem(position).getSender() == 0);
// Changed to warpper
holder.warpper.setBackgroundResource(
isMine ? R.drawable.bubble_yellow : R.drawable.bubble_green);
// Added
holder.singleMessageContainer.setGravity(isMine ? Gravity.LEFT : Gravity.RIGHT);
return rowView;
}
}
And it should work.
only thing, is that you may see a warnning in the xml about one of the linear layout is useless, but it wont work without it.
Hope it will help you.

Resources