I am facing problem to implement two listview in scrollview. I have activity in which I have scrollview.
here is image what I want
layout design
actually design
I want to make invoice which contain two listviews one for items and one for tracking data. I am able to make listview height dynamically and also disable its click event. but now on listview I am not able to click or scroll screen.
all components are in scrollview. but I am not able to scroll scrollview when I touch on listviews.
here is code where I'm managing height of listview
public static boolean setListViewHeightBasedOnItems(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
float px = 500 * (listView.getResources().getDisplayMetrics().density);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Get padding
int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + totalPadding;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}`
I tried recyclerview and with this property
note_recyclerview.setNestedScrollingEnabled(false);
but I didn't get what I want.
how can I achieve this?
Do not use ListView inside ScrollView.
As you are using multiple ListView, so you should use android.support.v4.widget.NestedScrollView instead of ScrollView to get proper scrolling behavior.
NestedScrollView is just like ScrollView, but it supports acting as
both a nested scrolling parent and child on both new and old versions
of Android. Nested scrolling is enabled by default.
See documentation.
Here is an example:
<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">
<ListView
android:id="#+id/listview1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<ListView
android:id="#+id/listview2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Hope this will help~
Related
In row.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">
<com.sample.utils.ExpandableTextView
android:id="#+id/tv_item_treatment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:minLines="2"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:singleLine="false"
android:text="Test treatments"
android:textColor="#android:color/black" />
For calculating listview hight programeticaly in Activity Class:
public void setListViewHeightBasedOnRow(ListView listView) {
if (listView == null) {
return;
}
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
I am using ListView in between ScrollView so i have to set hight programmatically of ListView for full activity scrolling.
But when the ExpandableTextView of row is expand then lower row are goes to hidden.
how to calculate and set the ListView hight in ExpandableTextView is in expand state?
Taken from ScrollView | Android Developers:
You should NEVER use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.
I am currently trying to use a preference fragment within a Navigation Drawer. There are multiple preference fragments that may populate a frame layout, all of which could be of a different size and may not be the full height of the parent.
For this reason I was wanting to use wrap_content for the frame layout height, but as preference fragment extends from ListView this causes problems (reference ListView Wrap Content). wrap_content does provide the desired result, although I can see that OnBindView is being called continuously, which highly inefficient and causes my data binding methods to be called all the time.
Has anyone got any simple out the box solutions I could try? Or would this be a case for a custom View where I would measure the children of the fragment and set the height at run time? Any help on this would be much appreciated.
The layout below shows the drawer layout which is included in the main layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="horizontal"
android:padding="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioGroup
android:id="#+id/drawer_radio"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:id="#+id/drawer_radio_button_0"
style="#style/ButtonDrawer"
android:background="#drawable/fft_button"
android:button="#null"
android:contentDescription="#string/image_button"/>
<RadioButton
android:id="#+id/drawer_radio_button_1"
style="#style/ButtonDrawer"
android:background="#drawable/trigger_button"
android:button="#null"
android:contentDescription="#string/image_button"/>
</RadioGroup>
</LinearLayout>
<FrameLayout
android:id="#+id/drawer_preference_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
tools:layout="#android:layout/simple_list_item_1"
android:background="#drawable/floating_preference_background_shape"/>
</LinearLayout>
Ok, so I think I found a good solution so I thought I'd post it for others to use.
The way I had to do this was to extend from PreferenceFragment and do some measurements at run time, in which I can use to resize the listView.
I did this with the following.
public class PreferenceFragmentHeightWrap extends PreferenceFragment {
/**
* We can guarantee that all children will be in the adaptor list by this point
*/
#Override
public void onResume() {
super.onResume();
setListViewHeightBasedOnItems(getView());
}
/**
* Sets ListView height dynamically based on the height of the items.
*
* #return true if the listView is successfully resized, false otherwise
*/
public boolean setListViewHeightBasedOnItems(View view) {
ListView listView = (ListView) view.findViewById(android.R.id.list);
ListAdapter listAdapter = listView.getAdapter();
if(listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for(int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
item.measure(0, 0);
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Set list height.
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + listView.getPaddingBottom()
+ listView.getPaddingTop();
view.setLayoutParams(params);
return true;
} else {
return false;
}
}
Hopefully this will make sense and feel free to comment if you see anything untoward.
Basically I need to have some content that is dynamically available through an adapter to populate the header of my expandableListView, this must be possible but it's been a really hard time finding any resources on this issue.
Here is a representation of what I'm looking to do.
Yes, but you'll need to override onGlobalLayout(), and set a height for the listView in the header e.g.
final ExpandableListView lExpView = (ExpandableListView) view.findViewById(R.id.expandable_list);
View viewHdr = getActivity().getLayoutInflater().inflate(R.layout.pager_header, lExpView, false);
final ListView lView = (ListView) viewHdr.findViewById(R.id.item_hdr_list);
...
lView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
if (lView.getVisibility() == View.VISIBLE) adjustTotalHeightOfListView(lView, lExpView);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
lExpView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
lExpView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
Where adjustTotalHeightOfListView() is a method of your own devising that can calculate and set the height of your listView, while contained in the header of the expandable list view. If the individual items in the listView can be more than one Text line in height (wider than the expandable list views width and you have WRAP_CONTENT set) this get's a bit complex, as the actual width of the containing ExpandableListView won't be available till it's rendered, but we need at least a guess before to allow this to happen. So you'll want some code that looks a bit like (not tested):
if (listView == null) return;
ListAdapter mAdapter = listView.getAdapter();
if (mAdapter == null) return;
int totalHeight = listView.getPaddingBottom() + listView.getPaddingTop();
int viewWidth = ( parent == null || parent.getWidth() <= 0 )
? listView.getWidth()
: parent.getWidth();
....
for (int i = 0; i < mAdapter.getCount(); i++) {
View mView = mAdapter.getView(i, null, listView);
mView.measure(
View.MeasureSpec.makeMeasureSpec(viewWidth, (viewWidth > 0)
? View.MeasureSpec.AT_MOST
: View.MeasureSpec.UNSPECIFIED
),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
);
totalHeight += mView.getMeasuredHeight() + listView.getDividerHeight();
}
....
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight;
listView.setLayoutParams(params);
listView.requestLayout();
Note: The ? View.MeasureSpec.AT_MOST : View.MeasureSpec.UNSPECIFIED hack in the measure() statement, essentially it's there to cope with a call being made before the parent view has been expanded / had a width set. If a width has been set don't exceed it, so if WRAP_CONTENT is specified and the width is greater than the parent the height will be adjusted, else assume you can be as wide as the content.
Where: pager_header.xml
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<ListView
android:id="#+id/item_hdr_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</GridLayout>
and the main layout contains:
<?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"
android:gravity="center">
<ExpandableListView
android:id="#+id/expandable_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:paddingBottom="10dp" />
</LinearLayout>
I have a profile page contains a linearlayout with some textviews and imageviews and a listview. (See picture)
The problem is that I want to make the whole page scrollable like in the twitter app instead of only the listview. So the listview need to extend to max height.
How can i force the listview to extend to max size and not be scrollable.
I linearlayout would be a second option but then it need to be possible to add a custom arrayadapter with a custom row like in the listview.
You can make this in two ways:
#1 Adding Header to your Listview
View header = inflater.inflate(R.layout.your_header_layout, null);
yourlistview.addHeader(header);
#2 You can set the list view height based on children.Call this fxn with your listview and keep all your widgets inside scrollview.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
Yes you can put the scroll view as parent view and make your custom class for your list view.
You can check my answer by this link
list view in scroll view
Use ScrollView to wrap your layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
......
</LinearLayout
</ScrollView>
Keep in mind that ScrollView takes in only one child. So adjust your original layout accordingly.
I am trying to have a listview with listviews as items, only the first row is visible in the inner listview(listview item).
My listview Item xml is :
<?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="wrap_content"
android:background="#drawable/main_bg" >
<ListView
android:id="#+id/numbers_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#null"
android:divider="#null" >
</ListView>
</RelativeLayout>
You can't have scrollable view in other scrollable views. The same happens if you put a list view in a ScrollView.
For your purpose, why not implement multiple view items type? Examples here or here.
inside of one scrollable view another won't scroll..
call this method after u set adapter and pass your listview..
private void setListViewHeight(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
http://kirukkupayal-mani.blogspot.in/2012/11/android-expandable-listview-inside.html