I have created a RecyclerView (in a fragment) in which I am adding items dynamically using GridLayoutManager. In each of the cell of RecyclerView I am loading images from the server using Picasso.
Now the problem is that, when the images are loading for the first time, the RecyclerView cells take weird height as shown here:
But when I change tab and come to the home tab again, everything is the way I want, as shown here:
What I need is, to make cells take the desired width and height at the time they are getting added to the recycler view. To achieve this I have tried:
Get the width of the screen and set cells' height and width = screen size /2.
Take the width of RecyclerView and make cells' width and height equals to half of it.
I am assigning dimensions to the cell in onCreateViewHolder method of the adapter.
But in any case, I need to change tab (load fragment again) to give the cells the desired height.
I have specified the width and height of cell in its layout file as wrap content because I want them to get set according to screen size. I don't wanna hard code any value.
What am I doing wrong? Did I miss anything?
For detailed explanation, the code is given as follows:
Cell layout file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/category_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#android:color/darker_gray"
android:orientation="vertical"
android:weightSum="1">
<ImageView
android:id="#+id/categoryImage"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="0dp"
android:layout_weight="0.8"
android:src="#drawable/icon" />
<TextView
android:id="#+id/categoryName"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="0dp"
android:layout_weight="0.2"
android:text="ORAL CARE"
android:textAlignment="center"
android:textColor="#android:color/black"
android:textSize="15dp" />
</LinearLayout>
RecyclerView in fragment's layout file:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewCategories"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView11" />
RecyclerView adapter:
public class CategoryRecyclerViewAdapter extends RecyclerView.Adapter<CategoryRecyclerViewAdapter.ViewHolder> {
private List<MedicineCategoryDataModel> categoryData = new ArrayList<MedicineCategoryDataModel>();
private LayoutInflater layoutInflater;
private ItemClickListener itemClickListener;
private Context context;
private int itemWidth;
public CategoryRecyclerViewAdapter(Context context, List<MedicineCategoryDataModel> data, int width) {
this.layoutInflater = LayoutInflater.from(context);
this.categoryData = data;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.layout_category_item, parent, false);
// this is the point where I was trying to set cell's width and height.
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String categoryName = categoryData.get(position).categoryName;
holder.textViewCategoryName.setText(categoryName);
String iconUrl = categoryData.get(position).iconUrl;
EPClientLayer.getInstance().getImageHandler().loadImage(context,iconUrl, holder.imageViewCategoryIcon);
}
#Override
public int getItemCount() {
return categoryData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textViewCategoryName;
ImageView imageViewCategoryIcon;
ViewHolder(View itemView) {
super(itemView);
textViewCategoryName = (TextView) itemView.findViewById(R.id.categoryName);
imageViewCategoryIcon = (ImageView) itemView.findViewById(R.id.categoryImage);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (itemClickListener != null) itemClickListener.onItemClick(view, getAdapterPosition());
}
}
public String getItem(int id) {
return categoryData.get(id).categoryName;
}
public void setClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
I think you need to set the height of the ImageView of your cell item to wrap_content instead of providing the height 0dp as you are taking the weightSum. I would like to recommend to implement your cell items like this.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/category_item"
android:layout_width="match_parent"
android:layout_height="260dp"
android:background="#android:color/darker_gray">
<ImageView
android:id="#+id/categoryImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/icon" />
<TextView
android:id="#+id/categoryName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/categoryImage"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="ORAL CARE"
android:textColor="#android:color/black"
android:textSize="15sp" />
</RelativeLayout>
And the RecyclerView to have the height and width set to match_parent.
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewCategories"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView11" />
You do not want to hard code any height, which is fine. However, I think you might consider hard-coding the optimized height of the cell item's root RelativeLayout to get the desired behaviour in all screen sizes.
make an SquareImageView as:
public class SquareImageView extends AppCompatImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);//replace heightMeasureSpec with widthMeasureSpec in this line
}
}
use above imageView in recyclerView Item to load image using Piccasa.
use recyclerView in xml as:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:spanCount="2"
tools:listitem="#layout/recycler_view_item"
app:layoutManager="GridLayoutManager">
</android.support.v7.widget.RecyclerView>
let me know if this solve your problem
I am making an application on leave management and I want to make my leave list layout like shown in the image I want to change the colour of list view on status change from the database. Now i just add the simple text view to show the list but i want to modify it like the image it will really helpful to me if you give me the code.
here is my java code adapter:
#NonNull
#Override
public LeaveViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.leave_list, null);
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
LeaveViewHolder viewHolder = new LeaveViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull LeaveViewHolder holder, int position) {
LeaveModel leave = leaveList.get(position);
holder.tVFrom_date.setText("From: " + leave.getFrom_date());
holder.tVTo_date.setText("To: " + leave.getTo_date());
holder.tVStatus.setText("Status: " + leave.getLeavestatus());
if (holder.tVStatus == null) {
} else {
}
}
#Override
public int getItemCount() {
return leaveList.size();
}
public class LeaveViewHolder extends RecyclerView.ViewHolder {
protected TextView tVFrom_date, tVTo_date, tVStatus;
public View container;
public LeaveViewHolder(View itemView) {
super(itemView);
tVFrom_date = itemView.findViewById(R.id.tVFrom_date);
tVTo_date = itemView.findViewById(R.id.tVTo_date);
tVStatus = itemView.findViewById(R.id.tVStatus);
}
}
Here is my Xml layout:
<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:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6dp"
android:paddingStart="6dp">
<TextView
android:id="#+id/tVFrom_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#color/Black"/>
<TextView
android:id="#+id/tVTo_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVFrom_date"
android:layout_marginTop="5dp"
android:textColor="#color/Black"/>
<TextView
android:id="#+id/tVStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVTo_date"
android:layout_marginTop="5dp"
android:textColor="#color/Red"
android:textStyle="bold" />
</RelativeLayout>
</android.support.v7.widget.CardView>
I have added image view in your layout so change color of this image view as par the status
<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:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardPreventCornerOverlap="true"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/img_LeaveAdapter_highlight"
android:layout_width="8dp"
android:layout_height="match_parent"
android:background="#color/colorPrimary" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6dp"
android:paddingStart="6dp">
<TextView
android:id="#+id/tVFrom_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#color/Black" />
<TextView
android:id="#+id/tVTo_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVFrom_date"
android:layout_marginTop="5dp"
android:textColor="#color/Black"
/>
<TextView
android:id="#+id/tVStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVTo_date"
android:layout_marginTop="5dp"
android:textColor="#color/Red"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
and i have created adapter just for your understanding
public class LeaveAdapter extends RecyclerView.Adapter<LeaveAdapter.MyViewHolder> {
Activity activity;
ArrayList<LeaveModel> list;
public LeaveAdapter(Activity activity, ArrayList<LeaveModel> list) {
this.activity = activity;
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_leaveadapter, parent, false);
return new MyViewHolder(rootView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
String leaveStatus = list.get(position).getLeaveStatus();
if (leaveStatus.equals("Panding for approval")) {
holder.img_LeaveAdapter_highlight.setBackgroundColor(ContextCompat.getColor(activity, R.color.Red));
} else if (leaveStatus.equals("Approved")) {
holder.img_LeaveAdapter_highlight.setBackgroundColor(ContextCompat.getColor(activity, R.color.Green));
}
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView img_LeaveAdapter_highlight;
public MyViewHolder(View itemView) {
super(itemView);
img_LeaveAdapter_highlight = itemView.findViewById(R.id.img_LeaveAdapter_highlight);
}
}
}
You have 2 options here:
In your RelativeLayout, add FrameLayout empty element and align left parent with full height and ~5dp width. Then in your onBindViewHolder() set FrameLayout background colour as you need. Of course, this option is simple shape (Rectangle)
If the shape you want is specific, also in RelativeLayout, add .PNG image and set backgroundTint programmatically
Recyclerview is not displayed in fullscreen. Below is the layout file and the code I've written. After executing, the contents are displayed as shown in the below picture. The height is only the highlighted part. I want the contents to be fullscreen. I remaining contents are within this highlighted area which is scrollable. I want the contents to be displayed in fullscreen. Any help would be helpful.
Layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/activity_search"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:clickable="true">
<TextView
android:id="#+id/title"
android:textSize="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/genre"
android:layout_below="#id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/year"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
Code:
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class setSearchData extends RecyclerView.Adapter<setSearchData.MyViewHolder> {
private List<SearchDisplayContents> moviesList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, year, genre;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
genre = (TextView) view.findViewById(R.id.genre);
year = (TextView) view.findViewById(R.id.year);
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_searchresults, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
SearchDisplayContents movie = moviesList.get(position);
holder.title.setText(movie.getTitle());
holder.genre.setText(movie.getGenre());
holder.year.setText(movie.getYear());
}
#Override
public int getItemCount() {
return moviesList.size();
}
}
Calling function code:
List<SearchDisplayContents> movieList = new ArrayList<>();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
setSearchData mAdapter = new setSearchData(movieList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
SearchDisplayContents movie = new SearchDisplayContents("Mad Max: Fury Road", "Action & Adventure", "2015");
movieList.add(movie);
movie = new SearchDisplayContents("Inside Out", "Animation, Kids & Family", "2015");
movieList.add(movie);
mAdapter.notifyDataSetChanged();
You should use different layout for your viewholder. Take the RelativeLayout you have there, cut it out, put it in different xml file then pass it to onCreateViewHolder.
From look at your code - it looks like what is in the preview screenshot is the same as what is within the RelativeLayout you have staticly defined.
There is an issue with your approach. It is that you are referencing the RelativeLayout (within the same xml hierarchy as your RecylerView) as the CellViewHolder in the RecyclerView.Adapter. My approach personally is to create a seperate xml layout for the cell viewholder.
Follow this guide, it is very detailed:
https://guides.codepath.com/android/using-the-recyclerview
You should use different layout for your viewholder. Take the RelativeLayout you have there, cut it out, put it in different xml file then pass it to onCreateViewHolder.
The above coding has something work use different layout mean one for Recycleview and other for contents in list
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/uslist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="#dimen/_49sdp"
android:divider="#android:color/transparent" />
</RelativeLayout>
list_content.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:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:clickable="true">
<TextView
android:id="#+id/title"
android:textSize="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/genre"
android:layout_below="#id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/year"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content" />
</RelativeLayout>
Adapter.java
public class yourAdapter extends RecyclerView.Adapter<yourAdapter .SimpleViewHolder> {
ArrayList<UsageRPDetails> mylist;
private Context mContext;
public yourAdapter (Context context, ArrayList<yourArray or model> checklist) {
mContext = context;
mylist = checklist;
}
#Override
public yourAdapter .SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_content, parent, false);
return new yourAdapter .SimpleViewHolder(view);
}
#Override
public void onBindViewHolder(final yourAdapter .SimpleViewHolder holder, final int position) {
holder.title.setText();
holder.year.setText();
holder.genre.setText();
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public int getItemCount() {
return mylist.size();
}
#Override
public int getItemViewType(int i) {
return 0;
}
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.title)
TextView title;
#Bind(R.id.genre)
TextView genre;
#Bind(R.id.year)
TextView year;
public SimpleViewHolder(View itemView) {
super(itemView);
title= (TextView) itemView.findViewById(R.id.title);
genre= (TextView) itemView.findViewById(R.id.genre);
genre= (TextView) itemView.findViewById(R.id.genre);
}
}
}
Also write a java file for Activity that calls this adapter class and call the recycleview in this activity
I am having trouble with a scrolling ListView inside a ScrollView. I have an Activity which has some EditTexts in the top part and then a tab host with two tabs which have one ListView each. When the EditText views are focused, the soft keyboard comes up and as I have a ScrollView, the content is scrollable. But the problem comes when there are more items in ListViews (ones in tabs), I am not able to scroll the ListView, even if there are more items.
The following is the layout XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="?backgroundImage"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:layout_margin="10dip"
android:id="#+id/buttons">
<Button
android:text="Save"
android:layout_margin="2dip"
android:textSize="20dip"
android:id="#+id/btnSaveorUpdate"
android:layout_height="wrap_content"
android:layout_width="145dip"></Button>
<Button
android:text="Cancel"
android:layout_margin="2dip"
android:textSize="20dip"
android:id="#+id/btnCancelorDelete"
android:layout_height="wrap_content"
android:layout_width="145dip"></Button>
</LinearLayout>
<ScrollView
android:layout_above="#id/buttons"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:layout_margin="10dip">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dip">
<TextView
android:text="Bill details"
android:textColor="?textColorDark"
android:layout_alignParentTop="true"
android:id="#+id/txtEnterDetails"
android:textSize="25dip"
android:textStyle="bold"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginBottom="2dip"></TextView>
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0dip"
android:layout_height="0dip" />
<EditText
android:layout_width="fill_parent"
android:hint="Enter data"
android:inputType="numberDecimal"
android:id="#+id/txtSample"
android:textSize="#dimen/editText"
android:layout_height="#dimen/editTextHeight"
android:text=""></EditText>
<EditText
android:layout_width="fill_parent"
android:id="#+id/txtDescription"
android:hint="Enter description"
android:textSize="#dimen/editText"
android:layout_height="#dimen/editTextHeight"
android:inputType="text"
android:text=""></EditText>
<EditText
android:layout_width="fill_parent"
android:id="#+id/txtComment"
android:hint="Enter comment (if any)"
android:textSize="#dimen/editText"
android:layout_height="#dimen/editTextHeight"
android:inputType="text"
android:text=""></EditText>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txtDate"
android:layout_width="wrap_content"
android:text=""
android:textSize="20dip"
android:textColor="?textColorDark"
android:layout_marginLeft="10dip"
android:layout_height="#dimen/editTextHeight"
android:layout_gravity="center_vertical" />
<Button
android:id="#+id/btnPickDate"
android:layout_width="wrap_content"
android:layout_height="#dimen/editTextHeight"
android:text="Select date"
android:layout_margin="2dip"
android:textSize="15dip"
android:layout_gravity="center_vertical" />
</LinearLayout>
<TabHost
android:id="#+id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#android:id/tabs"></TabWidget>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#android:id/tabcontent">
<ScrollView
android:layout_above="#id/buttons"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:id="#+id/tab1">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TableLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TableRow
android:id="#+id/tableRow1"
android:layout_marginLeft="2dip"
android:layout_marginRight="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:src="#drawable/ic_menu_invite"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_gravity="center_vertical"></ImageView>
<TextView
android:text="Add friend"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_centerVertical="true"
android:textColor="?textColorDark"
android:textSize="#dimen/editText"
android:layout_gravity="center_vertical" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip">
<TextView
android:id="#+id/txtData1"
android:layout_width="170dip"
android:layout_height="wrap_content"
android:text="Data"
android:textSize="14dip"
android:textStyle="bold"
android:textColor="#000000">
</TextView>
<TextView
android:id="#+id/txtData2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample"
android:textSize="13dip"
android:textColor="#000000"></TextView>
</TableRow>
</TableLayout>
<ListView
android:cacheColorHint="#00000000"
android:id="#+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:id="#+id/tab2"
android:orientation="vertical">
<TableLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TableRow
android:id="#+id/tableRow2"
android:layout_marginLeft="2dip"
android:layout_marginRight="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:src="#drawable/ic_menu_invite"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_gravity="center_vertical"></ImageView>
<TextView
android:text="Sample"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_centerVertical="true"
android:textColor="?textColorDark"
android:textSize="#dimen/editText"
android:layout_gravity="center_vertical" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip">
<TextView
android:id="#+id/txtUser1"
android:layout_width="170dip"
android:layout_height="wrap_content"
android:text="User"
android:textSize="14dip"
android:textStyle="bold"
android:textColor="#000000">
</TextView>
<TextView
android:id="#+id/txtUserData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UserData"
android:textSize="13dip"
android:textColor="#000000"></TextView>
</TableRow>
</TableLayout>
<ListView
android:cacheColorHint="#00000000"
android:id="#+id/ListView02"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>
</ScrollView>
</RelativeLayout>
Please can anyone tell me what the problem is here? I have another post on the ListView inside ScrollView problem, but they were of no use in my case.
I found a solution that works excellently and can scroll the ListView without problems:
ListView lv = (ListView)findViewById(R.id.myListView); // your listview inside scrollview
lv.setOnTouchListener(new ListView.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle ListView touch events.
v.onTouchEvent(event);
return true;
}
});
What this does is disable the TouchEvents on the ScrollView and make the ListView intercept them. It is simple and works all the time.
You shouldn't put a ListView inside a ScrollView because the ListView class implements its own scrolling and it just doesn't receive gestures because they all are handled by the parent ScrollView. I strongly recommend you to simplify your layout somehow. For example you can add views you want to be scrolled to the ListView as headers or footers.
UPDATE:
Starting from API Level 21 (Lollipop) nested scroll containers are officially supported by Android SDK. There're a bunch of methods in View and ViewGroup classes which provide this functionality. To make nested scrolling work on the Lollipop you have to enable it for a child scroll view by adding android:nestedScrollingEnabled="true" to its XML declaration or by explicitly calling setNestedScrollingEnabled(true).
If you want to make nested scrolling work on pre-Lollipop devices, which you probably do, you have to use corresponding utility classes from the Support library. First you have to replace you ScrollView with NestedScrollView. The latter implements both NestedScrollingParent and NestedScrollingChild so it can be used as a parent or a child scroll container.
But ListView doesn't support nested scrolling, therefore you need to subclass it and implement NestedScrollingChild. Fortunately, the Support library provides NestedScrollingChildHelper class, so you just have to create an instance of this class and call its methods from the corresponding methods of your view class.
I have also one solution. I always use this method. Try this
<ScrollView
android:id="#+id/createdrill_scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="15dp" >
<net.thepaksoft.fdtrainer.NestedListView
android:id="#+id/crewList"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:layout_weight="1"
android:background="#drawable/round_shape"
android:cacheColorHint="#00000000" >
</net.thepaksoft.fdtrainer.NestedListView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="15dp" >
<net.thepaksoft.fdtrainer.NestedListView
android:id="#+id/benchmarksList"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:layout_weight="1"
android:background="#drawable/round_shape"
android:cacheColorHint="#00000000" >
</net.thepaksoft.fdtrainer.NestedListView>
</LinearLayout>
</ScrollView>
NestedListView.java class:
public class NestedListView extends ListView implements OnTouchListener, OnScrollListener {
private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;
public NestedListView(Context context, AttributeSet attrs) {
super(context, attrs);
listViewTouchAction = -1;
setOnScrollListener(this);
setOnTouchListener(this);
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, -1);
}
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty()) {
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
}
newHeight += getDividerHeight() * listPosition;
}
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
if (newHeight > heightSize) {
newHeight = heightSize;
}
}
} else {
newHeight = getMeasuredHeight();
}
setMeasuredDimension(getMeasuredWidth(), newHeight);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, 1);
}
}
return false;
}
}
You have to just replace your <ScrollView ></ScrollView> with this Custom ScrollView like <com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >
package com.tmd.utils;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false" );
return false;
default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action ); break;
}
return false;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
I had a same issue and while googling I found your question. Yes marked answer worked for me also but there was some issue. Anyways I found another solution.
which works perfectly without doing any jugglery.
I know this question is asked long ago, but who ever is stuck for now can solve this by adding this line into your ListView
android:nestedScrollingEnabled="true"
For Example -
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true" />
Here is the exact method of using Listview with in the Scrollview. All we have to handle touch events.
lstvNextTracks.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
Log.e("Lisview *************", "focused");
SCView.requestDisallowInterceptTouchEvent(true);
return false;
}
});
SCView.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
int arr[] = new int[] { 1, 2 };
lstvNextTracks.getLocationOnScreen(arr);
/* Get bounds of child Listview*/
int lstvTop = arr[0];
int lstvBottom = arr[1] + lstvNextTracks.getHeight();
int lstvLeft = arr[1];
int lstvRight = arr[0] + lstvNextTracks.getWidth();
float x = event.getRawX();
float y = event.getRawY();
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
/*check if child ListView bounds are touched*/
if (x > lstvTop && x < lstvBottom && y > lstvLeft && y < lstvRight)
{
SCView.clearFocus();
/*This statement tells the ScrollView to do not handle this touch event, so the child Listview will handle this touch event and will scroll */
SCView.requestDisallowInterceptTouchEvent(true);
/*The child Listview isFocusable attribute must be set to true otherwise it will not work*/
lstvNextTracks.requestFocus();
return true;
} else
return false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE)
{
if (x > lstvTop && x < lstvBottom && y > lstvLeft && y < lstvRight)
{
SCView.clearFocus();
SCView.requestDisallowInterceptTouchEvent(true);
lstvNextTracks.requestFocus();
return true;
} else
return false;
} else if (event.getAction() == MotionEvent.ACTION_UP)
{
SCView.clearFocus();
SCView.requestDisallowInterceptTouchEvent(true);
lstvNextTracks.requestFocus();
return false;
} else
{
return false;
}
}
});
Use the following method and enjoy!
private void setListViewScrollable(final ListView list) {
list.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
listViewTouchAction = event.getAction();
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
list.scrollBy(0, 1);
}
return false;
}
});
list.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
list.scrollBy(0, -1);
}
}
});
}
listViewTouchAction is a global integer value.
If you can replace the line
list.scrollBy(0, 1);
with something else please share it with us.
Enjoy!
Its a bad practice to have two different scrolling views together. ListView itself has its own scrolling functionality and height is auto adjusted according to Adapter settings for your row items (Keelping in mind, we are not setting specific height to ListView in our Layout xml). However in your case, you can replace ListView with a class and this will adjust height for your ListView keeping in mind that your ListView is inside ScrollView.
This will help you:
public class ExpandableHeightListview extends ListView
{
boolean expanded = false;
public ExpandableHeightListview(Context context)
{
super(context);
}
public ExpandableHeightListview(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListview(Context context, AttributeSet attrs,int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
Now extend your ListView with this class, just change your ListView tag from your resource xml to smothing like this,
<yourpackagename.ExpandableHeightListview
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/White"
android:scrollbars="none"
android:orientation="vertical"
android:fadingEdge="none">
</cyourpackagename.ExpandableHeightListview>
This will solve your scrolling problem of ListView, as now the parent scrolling is managed by ScrollView rather then ListView.
I've similar issue and resolved by creating custom class by extending with ListView.
ScrollableListView.java
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class ScrollableListView extends ListView {
public ScrollableListView (Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollableListView (Context context) {
super(context);
}
public ScrollableListView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Usage:
<com.my.package.ScrollableListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Add:
android:nestedScrollingEnabled="true"
requestDisallowInterceptTouchEvent (boolean disallowIntercept)
Called when a child does not want this parent and its ancestors to intercept touch events with onInterceptTouchEvent(MotionEvent).
This parent should pass this call onto its parents. This parent must obey this request for the duration of the touch (that is, only clear the flag after this parent has received an up or a cancel.
Try this answer,
listview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of child view
scrollView.requestDisallowInterceptTouchEvent(true);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_UP:
scrollView.requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
});
The best solution is to use NestedScrollVew with RecyclerView or if you want to go with Listview then you can add header and footer view to this.
For example:
View footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.outofoffice_footer_view, null, false);
infoListView.addFooterView(footerView);
I have tried and tested nearly all the methods mentioned above, trust me, after completely running away from RecyclerView, I replaced my ListView with RecyclerView and it worked perfectly. Didnt need any 3rd Party library for ExtendedHeightListView and all, just plain and simple RecyclerView.
So Heres my Layout file before recyclerView:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="5dp">
<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:id="#+id/relativeLayoutre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
tools:context="com.example.android.udamovappv3.activities.DetailedActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar_detail"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="top"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<TextView
android:id="#+id/title_name"
android:layout_width="fill_parent"
android:layout_height="128dp"
android:layout_alignParentStart="true"
android:layout_marginTop="59dp"
android:background="#079ED9"
android:gravity="left|center"
android:padding="25dp"
android:text="Name"
android:textColor="#ffffff"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#+id/my_toolbar_detail"
app:layout_constraintVertical_bias="0.0"
tools:layout_editor_absoluteX="0dp" />
<ImageView
android:id="#+id/iv_poster"
android:layout_width="131dp"
android:layout_height="163dp"
android:layout_alignStart="#+id/my_toolbar_detail"
android:layout_below="#+id/title_name"
android:layout_marginBottom="15dp"
android:layout_marginRight="8dp"
android:layout_marginTop="15dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<Button
android:id="#+id/bt_mark_as_fav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/iv_poster"
android:layout_alignParentEnd="true"
android:layout_marginBottom="11dp"
android:layout_marginEnd="50dp"
android:background="#079ED9"
android:text="Mark As \n Favorite"
android:textSize="10dp" />
<TextView
android:id="#+id/tv_runTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/tv_rating"
android:layout_below="#+id/tv_releaseDate"
android:layout_marginTop="11dp"
android:text="TextView"
android:textSize="20sp" />
<TextView
android:id="#+id/tv_releaseDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/tv_runTime"
android:layout_alignTop="#+id/iv_poster"
android:text="TextView"
android:textSize="25dp" />
<TextView
android:id="#+id/tv_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/bt_mark_as_fav"
android:layout_below="#+id/tv_runTime"
android:layout_marginTop="11dp"
android:text="TextView" />
<TextView
android:id="#+id/tv_overview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/iv_poster"
android:layout_centerHorizontal="true"
android:layout_marginBottom="5dp"
android:foregroundGravity="center"
android:text="adasdasdfadfsasdfasdfasdfasdfnb agfjuanfalsbdfjbdfklbdnfkjasbnf;kasbdnf;kbdfas;kdjabnf;lbdnfo;aidsnfl';asdfj'plasdfj'pdaskjf'asfj'p[asdfk"
android:textColor="#000000"
/>
<RelativeLayout
android:id="#+id/foodItemActvity_linearLayout_fragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="#+id/tv_overview">
<TextView
android:id="#+id/fragment_dds_review_textView_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reviews:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<com.github.paolorotolo.expandableheightlistview.ExpandableHeightListView
android:id="#+id/expandable_listview"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/fragment_dds_review_textView_label"
android:padding="8dp">
</com.github.paolorotolo.expandableheightlistview.ExpandableHeightListView>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
THIS IS AFTER REPLACING MY LISTVIEW WITH ONE OF THE MANY SOLUTIONS MENTIONED ABOVE. So the problem was that the listview was not behaving properly due to 2 scrollview bug(maybe not a bug) in android.
I replaced the
with recycler view to form form my final layout.
This is my recycler view adapter:
public class TrailerAdapter extends RecyclerView.Adapter<TrailerAdapter.TrailerAdapterViewHolder> {
private ArrayList<String> Youtube_URLS;
private Context Context;
public TrailerAdapter(Context context, ArrayList<String> Youtube_URLS){
this.Context = context;
this.Youtube_URLS = Youtube_URLS;
}
#Override
public TrailerAdapter.TrailerAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.trailer_layout, parent, false);
return new TrailerAdapterViewHolder(view);
}
#Override
public void onBindViewHolder(TrailerAdapter.TrailerAdapterViewHolder holder, int position) {
Picasso.with(Context).load(R.drawable.ic_play_arrow_black_24dp).into(holder.iv_playbutton);
holder.item_id.setText(Youtube_URLS.get(position));
}
#Override
public int getItemCount() {
if(Youtube_URLS.size()==0){
return 0;
}else{
return Youtube_URLS.size();
}
}
public class TrailerAdapterViewHolder extends RecyclerView.ViewHolder {
ImageView iv_playbutton;
TextView item_id;
public TrailerAdapterViewHolder(View itemView) {
super(itemView);
iv_playbutton = (ImageView)itemView.findViewById(R.id.play_button);
item_id = (TextView)itemView.findViewById(R.id.tv_trailer_sequence);
}
}
}
And this is my RecyclerView custom layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="56dp"
android:padding="6dip" >
<ImageView
android:id="#+id/play_button"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_marginRight="6dip"
android:layout_marginStart="12dp"
android:src="#drawable/ic_play_arrow_black_24dp"
android:layout_centerVertical="true"
android:layout_alignParentStart="true" />
<TextView
android:id="#+id/tv_trailer_sequence"
android:layout_width="wrap_content"
android:layout_height="26dip"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/play_button"
android:ellipsize="marquee"
android:gravity="center"
android:maxLines="1"
android:text="Description"
android:textSize="12sp" />
</RelativeLayout>
And VOILA, I got the desired effect of ListView(Now RecyclerView) within a scollview.
Heres the Final Image of the UI
On a final note, I believe that replacing the RecyclerView was a better choice for me, as it improved the overall app stability, and also helped me understand RecyclerView better. If I were to suggest a solution, Im going to say replace your ListView with a RecyclerView.
I have had this error.And my solution is following as:
1. Create a custom listview which is non scrollable
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
2. Use above custom class for xml file
<com.Example.NonScrollListView
android:id="#+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
Hope best for you.
Above solution given by #Shailesh Rohit works perfectly fine. Some tricks has to be done.
If you are putting helper class inside the same class( main class) then make Helper class as static and getListViewSize() not be static.
Most important, write "Helper.getListViewSize(listView);" statement after setting adapter for the first time like "listView.setAdapter(myAdapter);" as well as when ever you are using "myAdapter.notifyDataSetChanged();"
Usage is shown below.
listView = (ListView) findViewById(R.id.listView);
myAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, listValues);
listView .setAdapter(myAdapter);
Helper.getListViewSizelistView(listView);
myAdapter.notifyDataSetChanged();
Helper.getListViewSizelistView(listView);
Best Code
<android.support.v4.widget.NestedScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/btmlyt"
android:layout_below="#+id/deshead_tv">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="#+id/des_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/btmlyt"
android:background="#android:color/white"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:scrollbars="vertical"
android:paddingTop="3dp"
android:text="description"
android:textColor="#android:color/black"
android:textSize="18sp" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Here is the best example
Add NestedScrollView instead of Scrollview
Add this line in ListView android:nestedScrollingEnabled="true"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true"
/>
</androidx.core.widget.NestedScrollView>
Demo_ListView_In_ScrollView
==============================
package com.app.custom_seekbar;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class Demo_ListView_In_ScrollView extends Activity
{
ListView listview;
ArrayList<String> data=null;
listview_adapter adapter=null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
super.setContentView(R.layout.demo_listview_in_scrollview_activity);
init();
set_data();
set_adapter();
}
public void init()
{
listview=(ListView)findViewById(R.id.listView1);
data=new ArrayList<String>();
}
public void set_data()
{
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
}
public void set_adapter()
{
adapter=new listview_adapter(Demo_ListView_In_ScrollView.this,data);
listview.setAdapter(adapter);
Helper.getListViewSize(listview); // set height of listview according to Arraylist item
}
}
========================
listview_adapter
==========================
package com.app.custom_seekbar;
import java.util.ArrayList;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
public class listview_adapter extends ArrayAdapter<String>
{
private final Activity context;
ArrayList<String>data;
class ViewHolder
{
public TextView tv_name;
public ScrollView scroll;
public LinearLayout l1;
}
public listview_adapter(Activity context, ArrayList<String> all_data) {
super(context, R.layout.item_list_xml, all_data);
this.context = context;
data=all_data;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder viewHolder;
if (rowView == null)
{
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.item_list_xml, null);
viewHolder = new ViewHolder();
viewHolder.tv_name=(TextView)rowView.findViewById(R.id.textView1);
rowView.setTag(viewHolder);
}
else
viewHolder = (ViewHolder) rowView.getTag();
viewHolder.tv_name.setText(data.get(position).toString());
return rowView;
}
}
===================================
Helper class (source: https://www.androidhub4you.com/2012/12/listview-into-scrollview-in-android.html)
====================================
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
public class Helper {
public static void getListViewSize(ListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null) {
//do nothing return null
return;
}
//set listAdapter in loop for getting final size
int totalHeight = 0;
for (int size = 0; size < myListAdapter.getCount(); size++) {
View listItem = myListAdapter.getView(size, null, myListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
//setting listview item in adapter
ViewGroup.LayoutParams params = myListView.getLayoutParams();
params.height = totalHeight + (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));
myListView.setLayoutParams(params);
// print height of adapter on log
Log.i("height of listItem:", String.valueOf(totalHeight));
}
}
========================
demo_listview_in_scrollview_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" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
</ScrollView>
</LinearLayout>
================
item_list_xml.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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="TextView"
android:textSize="14sp" />
</LinearLayout>
As According to me while you are using setOnTouchListener om parent or child stop the scrolling of parent as you touch on child else stop scrolling of child as you touch on parent
Try this with ScrollView, not with ListView.
public class xScrollView extends ScrollView
{
;
;
#Override
public boolean onInterceptTouchEvent (MotionEvent ev)
{
return false;
}
}
replace ListView by RecycleView inside ScrollView. it runs smoothly without additional source code:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.hung.recycleviewtest.MainActivityFragment"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycle_view"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#android:color/darker_gray"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycle_view_a"
android:layout_marginTop="40dp"
android:layout_below="#id/recycle_view"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#android:color/darker_gray"/>
</RelativeLayout>
</ScrollView>
For ListView inside ScrollView use NestedScrollView it can handle this
functionality very easily:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dip"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
I found a solution for that,
Instead of using scrollview, You can use addHeaderview and addFooterview of listview
Here is my snippet,
// create separate layout and add it dynamically
scrollview=getLayoutInflater().inflate(R.layout.yourlayout,null);
lv=(ListView)listview.findViewById(R.id.listView2);
lv.addHeaderView(scrollview);
lv.setContentView(lv);
Now, with the listview your layout also can be scrolled. Enjoy it!!!
Replace ScrollView by android.support.v4.widget.NestedScrollView inside xml. it runs
1) Use in XML:::: android.support.v4.widget.NestedScrollView
instead of:::: ScrollView
2) And use for list view in this way using NonScrollListView in cs file:
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
3) Finally use this code to identify scrollview in cs file:
NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
You cannot add a ListView in a scroll View, as list view also scolls and there would be a synchonization problem between listview scroll and scroll view scoll.
You can make a CustomList View and add this method into it.
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* Prevent parent controls from stealing our events once we've gotten a touch down
*/
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
ViewParent p = getParent();
if (p != null) {
p.requestDisallowInterceptTouchEvent(true);
}
}
return false;
}
Dont give scroll view to ListView, coz it has that setting default
<ListView
android:cacheColorHint="#00000000"
android:id="#+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />