This is my list i want My problem is when i scroll list view then the check boxes(which are the items of this List ) are automatically checked
ex - if i checked first then 4 automatically being checked.
My first goal:
1. want to stretch my list to full i will wrap it into Scrollview how
2. i can prevent it to automatically checked
.
<ListView
android:id="#+id/ListViewProducts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_span="2"
android:clickable="true"
android:isScrollContainer="true"
android:saveEnabled="true"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarSize="10sp"
android:scrollbars="vertical" >
</ListView>
Create your own BaseAdapter.
Keep in mind, that ALL views in your listview you see are temporary. They will be recycled when you'll scroll away. The reason is - you can have >9000 elements in your list. So, the way you create views must depend on some kind of (!) data.
Here is nince tutorial on how to create your own list.
Make X-th checkbox depend on X-th boolean in the list. A bit confusing first time I know, but this is the best way.
class MyAdapter extends BaseAdapter{
List<boolean> myCheckBoxes;
boolean getItem(int arg0){
return myCheckBoxes.get(arg0);
}
View getView(int arg0, View arg1, ViewGroup arg2){
...
...//See article
myView.setChecked(getItem(arg0));
...
return myView;
}
And in your activity
ListView myListView;
...
myListView.setAdapter(new MyAdapger(...));
You can't put a listview into a scrollview, two views scrolling in the same direction will not work nicely. Just put the listview in your non scrolling layout (frame- , list-, relativelayout).
Use an Adapter that sets every listview's row's views according to the data to be displayed.
ListView already extends ScrollView and doesn't need to have another one to surround it.
try looking at this post on creating custom listView items. you can implement a checkBox in them and make is have android:checked="false"
ListVew already extends ScrollView no need to implement it on ListView
for AutoCheck follow this link:
Check box checked Automatically in listview when scrolling the list.
There's no need to implement scrollview in listview becoz it is already extends to scrollview.
I think your listview is not able to handle the recycling of items properly.So to solve this problem go through the below link.
Getting an issue while checking the dynamically generated checkbox through list view
Related
I am trying to dynamically add information to a ListView. The information I am adding consists of a "Device Name" (the main item) and "MAC Address" (the sub item). An example from online is below. Note: I want to replace Item 1 with a device 1's name, sub item 1 with device 1's MAC address, and so on. This MUST be done dynamically because the list is being populated as devices are scanned for.
.
Before this is marked as a repeat, I have looked at the following questions and they have not helped me: Adding ListView Sub Item Text in Android, How to add subitems in a ListView, Adding Items and Subitems to a ListView
The conclusion I have come to through reading these questions is that I need to implement a custom ArrayAdapter and override the getView() method. I have created a custom layout with two text views in it:
cyan_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/main_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/cyan"/>
<TextView
android:id="#+id/sub_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/dark_cyan"/>
</LinearLayout>
I then try to create a custom ArrayAdapter in my Activity class, but I am lost as to what to put in my public View getView(final int position, View convertView, ViewGroup parent) method. Additionally, is creating a custom ArrayAdapter necessary if all I am trying to do is add a textview sub item?
The answer to your question is: NO, you don't need to create a custom ArrayAdapter if you just want to add items. I recommend, however, creating it if your layout is customized, as you'll gain so much control over the items you're displaying. You didn't add your code where you create your ArrayAdapter, but in your case I'd use this constructor. The important part is the third parameter: In your activity, you should store an ArrayList with the initial items you're adding to your ArrayAdapter, then, if you want to add a new item, you simply add it to the ArrayAdapter and call notifyDataSetChanged() on your adapter. Simply doing that, your item will be added to the layout and displayed. If you need to override the GetView method for your own ArrayAdapter, I recommend this link, it helped me understanding the whole thing.
are you searching some listview example in google like those tutorials :
http://www.vogella.com/tutorials/AndroidListView/article.html
http://www.mkyong.com/android/android-listview-example/
I think they explain step by step how to create a list adapter
You need to add getter method into your Adapter
YourAdapter ...{
List<Device> items = new ArrayList<Device>;
public List<Device> getItems(){
return items;
}
}
then change item that you need
...{
//for 1s item
Device item = getItems().get(0);
item.setTitle(macAdress)
}
and call notifyDataSetChanged for your adapter
...
yourListView.getAdapter().notifyDataSetChanged();
}
Thats it. Now you are able to change your list data.
And for your question, i think yes. Is better to create your own adapter in order to have simple possibility to exentd it later. And in your case (if you dont want to change your adapter after each title change) you deffinetly need custom one. Cheers
I have a form with a number of EditView fields in it. The data for these fields are loaded from a database (in the onCreate() method). The last object on the screen should be a ListView that should show all related data records to the record being show. All the data is correctly loading, and the adapter for this seems to work ok. It loads the correct data, it formats the data correctly into the two-line layout specified by the .xml used by the adapter.
The problem is that the ListView on the screen is "shrunk" to show only one item, and adds a scrollbar if there's more items. I expected the ListView to expand in size to show all records, and the screen itself being scrollable (everything is wrapped inside a ScrollView).
So, the XML looks like this:
<ScrollView
android:layout_height="wrap_content"
android:id="#+id/ScrollView1">
<RelativeLayout
android:layout_height="wrap_content"
android:id="#+id/RelativeLayout1">
<EditView
android:id="#+id/EditView1>
</EditView>
<ListView
android:id="#+id/ListView1
android:layout_height="wrap_content"
android:layout_below="#id/EditView1>
android:divider="#b5b5b5"
android:dividerHeight="1dp" />
I then use a custom BaseAdapter to fill data into the ListView
listView = (ListView) findViewById(R.id.ListView1);
dbRecords = db.getAllRecordsByRecordId(recordId);
CBA_Records adapter = new CBA_Records(this, dbRecords);
listView.setAdapter(adapter);
This is all the same stuff that I've done before, except this is all wrapped inside the scrollview. The reason for this is that there might be more fields than will fit on a smaller screen (or horizontal screen), so the screen must be scrollable. And, the listview must also be there ...
Any suggestions?
A little more onto what invertigo said. ListView inside a ScrollView is not recommended.
Make your ListView the root, and set it's width and height to "match_parent". Put the other stuff that's above the ListView (the header) in a separate xml. Then inflate the new xml file for the header use the addHeaderView() method to add it as a header to the ListView (it looks like you want everything to scroll).
ListView is vertically scrolling automatically, so you now have two vertical scroll areas, which do you expect to consume the scroll event? Either set your ListView to a static height (not recommended), or design your layout so only the area you want to scroll (ie the ListView) has scrolling capabilities and remove the ScrollView. Also set your base layout, in this case the RelativeLayout, to height=match-parent, and ListView height=0dp weight=1 to prevent the ListView from being "shrunk".
Alternatively, take a look at this solution if you dont want the ListView scrolling independantly: android listview display all available items without scroll with static header
I have ListView with custom Adapter which supplies View to ListView in this way:
public View getView(int position, View convertView, ViewGroup parent)
{
RelativeLayout.LayoutParams lineParams;
RelativeLayout line=new RelativeLayout(context);
TextView tv=new TextView(context);
tv.setText("Text in postion="+i);
lineParams=new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lineParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
line.addView(tv, lineParams);
lineParams.addRule(RelativeLayout.CENTER_IN_PARENT);
//checkbox
CheckBox checkBox=new CheckBox(context);
lineParams=new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lineParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
lineParams.addRule(RelativeLayout.CENTER_IN_PARENT);
line.addView(checkBox, lineParams);
return line;
}
And somewhere inside ListView there's setOnItemClickListener(), which should intercept item clicking events. My problem that, whenever I try to add checkbox to item - I don't get any responces from my ListView. If I skip CheckBox or any other Button it works.
I am really stuck with this problem, I have tried all kind of Layouts, aligning, wrapping and so on - useless. Looks like CheckBox interferes ListView item click events.
Any ideas how to overcome?
just add this line into the item views instead of listView itself
android:focusable="false"
check more detail about this from Android custom ListView unable to click on items
If you have ImageButtons inside the list item, you need to add:
android:descendantFocusability="blocksDescendants"
to the root list item element [such as the root layout].
Then within each ImageButton in the list item, you need to add:
android:focusableInTouchMode="true"
This worked for me - but I was using ImageButtons, not the standard button.
I have also faced the same issue I have tried to set android:focusable="false" to listview but it don't work then I add this to listview item.. like in my listview item I have uesed Toggle button which was creating problem, I add android:focusable="false" to Toggle button and listview on item click listener start work again
Add following line to your listView
android:choiceMode="singleChoice"
or make sure to set following lines to your layout text fields
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
I had also had the problem of a Button in my ListView. Unfortunately just setting the focus to false for all objects in my Adapter did not work for me.
I now have a workaround.
In your Adapter create an OnClickListener for the button (or other clickable object) if you have not already done that. In that OnClickListener you call the OnItemClickListener yourself.
public void onClick(View v) {
mOnItemClickListener.setOnItemClick(mListView, v, vPos, vId);
}
It does mean that you will need to give your adapter access to both the parent ListView and the OnItemClickListener.
You can consider to write your on OnTouchEvent in your listview item and send the proper touchEvent to you child view , the button .
Well i know none of the above solutions will work.I tried changing xml attributes but those does not work out, But i implemented it in a new fashion.
Here is how:
Create an interface CheckBoxOnCheckListener with method onCheckBoxChecked and pass needed parameters, implement interface CheckBoxOnCheckListener in your activity or fragment containing listView.
Next in your adapter, declare an mListener as CheckBoxOnCheckListener, and pass this as a parameter to Adapter's constructor from fragment/activity and cast it to CheckBoxOnCheckListener and assign to mListener.
Next set mListener as itemView.onClick or CheckBox.onCheckCheckedListener and onCheckChanged method call mListener.onCheckBoxChecked.
That's it. It will definitely work,it worked for me.
For code just pm.
If you are using ListView in Activity, ensure you have setup setOnItemClickListener()
myListView.setOnItemClickListener(this); // if your activity implement OnItemClickListener
I have a quite complex View build-up, and as a part of that, I have a ListView inside a LinearLayout within a ScrollView (and quite a lot more components, but they do not matter in this issue).
Now the whole activity scrolls nicely as it should, but the ListView has a limited height, and when the Items inside it surpass the height, the disappear of my screen. I've tried to place the ListView inside it's own ScrollView, but this doesn't work. When I try to scroll on the ListView, the main ScrollView is selected and my screen scrolls instead of the ListView.
My question may sound easy, but I haven't been able to fix this... Is it possible to make the ListView scrollable aswell?
The relevant XML:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="#+id/GlobalLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView android:id="#+id/EndpointList"
android:choiceMode="multipleChoice"
android:layout_height="175dip"
android:layout_width="fill_parent" />
</LinearLayout>
</ScrollView>
Instead of ListView with other layouts inside ScrollView create one ListView with header and footer.
Add views that should be above ListView as a header:
addHeaderView(View v)
and that below as a footer:
addFooterView(View v)
Put everything what should be above ListView to header of ListView and the same with footer.
LayoutInflater inflater = LayoutInflater.from(this);
mTop = inflater.inflate(R.layout.view_top, null);
mBottom = inflater.inflate(R.layout.view_bottom, null);
list.addHeaderView(mTop);
list.addFooterView(mBottom);
// add header and footer before setting adapter
list.setAdapter(mAdapter);
In result you'll get one scrollable view.
Actually, the way that I have it set up is really working... Placing a ListView in a LinearLayout within a ScrollView. Just avoid that the ListView is the direct child of the ScrollView, and it will work out just fine...
Just be aware that if there aren't enough items in the ListView to fill it so it goes 'off screen', that it won't scroll (kind of logically though). Also note that when you have enough items to scroll through, you need to keep pressing on an item in the ListView to make it scroll, and half of the time, focus is given to the global scrollview in stead of the ListView... To avoid this (most of the time), keep pressing on the most top or most down item, depending on which way you want to scroll.This will optimize your chance to get focus on your ListView.
I've made a video that it is possible, am uploading it now to YouTube...
Video is http://www.youtube.com/watch?v=c53oIg_3lKY. The quality is kinda bad, but it proves my point.
Just for a global overview, I used the ScrollView to be able to scroll my entire activity, the LinearLayout for the Activity's layout, and the ListView to, well, make the list...
I would like to just note something for the video
The listview is working once every x touches not because you placed it inside a linearlayout but because you are touching the the divider...
the scrollview will then consider that the place you touched does not have children to dispatch the motionevent to... so it calls the super.dispatchTouchEvent which is in this case the View.dispatchTouchView hence the listview.onTouchEvent.
When you touch inside a row the scrollview which is really a viewgroup will send the dispatch to the children in your case the textview and never calls the one of the view so the listview do not scroll.
Hope my explanation was clear enough to point out why is it not working.
I have a ListView. The data behind it is fetched from the Internet, in sets of 10-30 items whenever the user scrolls all the way to the bottom. In order to indicate that it is loading more items, I used addFooterView() to add a simple view that displays a "Loading..." message and a spinner. Now, when I'm out of data (no more data to fetch), I want to hide that message. I tried to do:
loadingView.setVisibility(View.GONE);
Unfortunately, while that does hide the view, it leaves space for it. I.e. I end up with a big blank space where the "Loading" message used to be. How can I go about properly hiding this view?
I can't use removeFooterView() because I may need to show it again, in which case I can't call addFooterView() again because an adapter has already been set on the ListView, and you can't call addHeaderView() / addFooterView() after setting an adapter.
It seems that you are allowed to call addHeaderView() / addFooterView() after setAdapter() as long as you call one of those methods at least once before. That is a rather poor design decision from Google, so I filed an issue. Combine this with removeFooterView() and you have my solution.
+1 for the other two answers I got, they're valid (and arguably more correct) solutions. Mine, however, is the simplest, and I like simplicity, so I'll mark my own answer as accepted.
Try setting the footer's height to 0px or 1px before hiding it. Alternatively, wrap the footer view in a wrap_content height FrameLayout and hide/show the inner view, leaving the FrameLayout visible; the height should wrap properly then.
in my case addFooterView / removeFooterView() cause some artefacts.
And I found other solution. I used FrameLayout as FooterView. And when I want to add Footer I called mFrameFooter.addView(myFooter); and mFrameFooter.removeAllViews(); for remove.
FrameLayout frameLayout = new FrameLayout(this);
listView.addFooterView(frameLayout);
......
......
//For adding footerView
frameLayout.removeAllViews();
frameLayout.addView(mFooterView);
//For hide FooterView
frameLayout.removeAllViews();
The Droid-Fu library has a class designed for having a loading footer show and hide: ListAdapterWithProgress.
Works well in my project:
1.Add footer view first
mListView.addFooterView(mFooterView);
mListView.setAdapter(mAdapter);
2.Set visibility
mFooterView.setVisibility(View.GONE);
mFooterView.setPadding(0, 0, 0, 0);
3.Set invisibility
mFooterView.setVisibility(View.GONE);
mFooterView.setPadding(0, -1*mFooterView.getHeight(), 0, 0);
As #YoniSamlan pointed out, it can be achieved in a simple way. You have to specify
android:layout_height="wrap_content"
in the ViewGroup that contains the "Load More" button. Doesn't have to be FrameLayout, see below for a simple -working- example that uses a LinearLayout.
Both images show a screen that is scrolled all the way to the bottom. First one has a visible footer that wraps around the "load more" button. Second images shows that the footer collapses if you set button's visibility to GONE.
You can show again the footer (inside some callback) by changing the visibility:
loadMore.setVisibility(View.VISIBLE); // set to View.GONE to hide it again
Perform listView initialization as usual
// Find View, set empty View if needed
mListView = (ListView) root.findViewById(R.id.reservations_search_results);
mListView.setEmptyView(root.findViewById(R.id.search_reservations_list_empty));
// Instantiate footerView using a LayoutInflater and add to listView
footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.load_more_footer_view, null, false);
// additionally, find the "load more button" inside the footer view
loadMore = footerView.findViewById(R.id.load_more);
loadMore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fetchData();
}
});
// add footer view to the list
mListView.addFooterView(footerView);
// after we're done setting the footerView, we can setAdapter
adapter = new ReservationsArrayAdapter(getActivity(), R.layout.list_item_reservations_search, reservationsList);
mListView.setAdapter(adapter);
load_more_footer_view.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="wrap_content">
<Button
android:id="#+id/load_more"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="9dp"
android:gravity="center"
android:layout_gravity="center"
android:background="#drawable/transparent_white_border"
android:textColor="#android:color/white"
android:text="#string/LOAD_MORE"/>
It should be a bug of Android.
You don't need to remove or add footer view dynamically. You just need to create an unspecified height parent Layout (either inflate it from an xml file or create it programatically) and then add your view which you want to hide or show into it.
And you can set the view, but NOT the parent Layout, to VISIBLE or GONE or something else now. It works for me.
Used
footer.removeAllViews();
This does not remove footer but flushes children.
You again have to repopulate children. Can check by
footer.getChildCount()<2
I also found that is possible call onContentChanged() (if you use ListActivity) to force recreate ListView if I need add HeaderView to them after setAdapter() call, but it is very ugly hack.
I have created a ListView that handles this. It also has an option to use the EndlessScrollListener I've created to handle endless listviews, that loads data until there's no more data to load.
You can see these classes here:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java
- Helper to make it possible to use the features without extending from SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java
- Listener that starts loading data when the user is about to reach the bottom of the ListView.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java
- The EndlessListView. You can use this class directly or extend from it.
I have small hack way to resolve this problem for everywhere.
Put listview and footer view (just sub layout) in parent layout like LinnearLayout, remember that footerview below listview.
Controller this footer view gone and visibility like nomal view. And done!
first I am adding my footer to the listview,like this
listView.addFooterView(Utils.b);
Then on button click , I remove the view,
listView.removeFooterView(Utils.b);
I am adding the footer everytime when I am hitting the async,and theus the're no duplicate entry.I could aslo check for the count and so it like this,
if(listView.getFooterViewsCount() > 0){//if footer is added already do something}
When you want to remove the footer in ListView just call
listView.addFooterView(new View(yourContext));
It will add a dummy empty view which will not reserve any space