I'm using a ListView with a custom adapter to receive a JSON response and put it into a nice list - works great.
I'm now testing various exceptions and error handling and am catching errors received from my web API within the Android app. This all works great, handles well - but for the life of me I can't work out how to change the 'empty view' of a ListView once it has been set once.
It's within a fragment, if that makes any difference - but the ProgressBar and ListView are defined in an XML layout which is inflated in the Fragment. I have a TextView also inside there which contains some error text - I want to know how to switch the ProgressBar out for the TextView onError()!
Edit: Currently the ListView uses the ProgressBar as the empty view - I want to know how to later change this to another view - XML defined or programmatic.
The UI thread is not being locked as all API calls are carried out on an AsyncTask, so that's not the issue.
ListView.removeAllViews() caused a fairly imminent crash.
Apologies if this is trivial...
You could define the empty view to be a FrameLayout and put whatever you want the empty state be inside that view and change it the way you'd change contents of any other view.
I have two empty views for my ListView. One is ProgressBar which I shows while I am loading data from database or server. Other is TextView, which I shows when I got error or have no data.
I put my ListView, ProgressBar and TextView in FrameLayout. And set visibility of both ProgressBar and TextView to Gone.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ListView
android:id="#+id/my_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="#+id/empty_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:text="#string/no_contacts_found"/>
<ProgressBar
android:id="#+id/empty_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
Before loading data from database or server, I change visibility of ProgressBar to Visible and set it as empty view of my ListView. So my ListView starts showing ProgressBar, indicating user that data is still loading.
If I got error or got no data from database or server, I set visibility of ProgressBar to Gone and change visibility of TextView to Visible. And then set TextView as empty view of my ListView.
I just found this code in an old project, should work fine:
View emptyView = inflater.inflate(R.layout.id_of_your_layoout_file, parent, false);
getListView.setEmptyView(emptyView);
Related
i have two view
<VideoView
android:id="#+id/player"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/lighter_gray"
android:id="#+id/imageView"
/>
I want to select only one view to shown at run time , is there container for them to do the job ?
i searched and found something like viewswitcher ,but i dont want to switch between them i only want to display one of them
You can set video view and image view visibility to gone in xml by adding android:visibility="gone"
and setVisibility to visible in java code based on the requirement or which view you want to show.
If you have hundreds of items in list.
You can simply managed by list adapter with one own type field and create custom adapter with the list and switch the views on each position as per your requirement.
I want a ListView to fill the space available to it while still leaving room for a small footer view at the bottom of the screen. I'm trying to use a RelativeLayout to accomplish this and attempted to use the solution discussed at Limit number of rows of listview . The problem I'm running into is I'm using nested Fragments, so my ListView is actually a FrameLayout in my xml then I load a ListFragment into that frame dynamically. Given the nested fragment stipulation, how can I get my FrameLayout to "stackFromBottom" as I would with a ListView? I just need to stop the list from pushing the other View off the bottom of the screen. Thanks for your time all.
Here is the solution I came up with:
<TextView
android:id="#+id/advertisement"
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="Ads will appear here"
android:gravity="center"
android:layout_alignParentBottom="true"/>
<FrameLayout
android:id="#+id/news_frag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/carousel_menu"
android:layout_above="#id/advertisement"/>
The trick was to set both layout_above AND layout_below for the FrameLayout, I had only been setting one and that was apparently allowing the layout to push it off of the screen. Also worth noting is they had to be declared in reverse order of how they actually appear on the page, so that the FrameLayout could properly reference the other View.
I have a GridView which shows a grid of 15 Views for the first time. Then, on click of a button, I add 5 more grid views. So, my question is: How to add a ProgressBar at the bottom of a page, when those 5 Views are loading ? Like a spinner loading and the 5 Views get updated.
Hi i have a tab host tabwidget for tabs and gridview inside framlayout..now if i want the progressbar then should i need to inclue this linearlayout after frame layout or inside frame laoyout?
Add this below your GridView in the XML.
<LinearLayout
android:id="#+id/linlaProgressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<ProgressBar
style="#style/Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp" />
</LinearLayout>
And in your Activity, where you are loading the data (assuming, it is an AsyncTask), in your onPreExecute() show it:
#Override
protected void onPreExecute() {
// SHOW THE BOTTOM PROGRESS BAR (SPINNER) WHILE LOADING MORE PHOTOS
linlaProgressBar.setVisibility(View.VISIBLE);
}
And in the onPostExecute(), hide it:
#Override
protected void onPostExecute() {
// SHOW THE BOTTOM PROGRESS BAR (SPINNER) WHILE LOADING MORE PHOTOS
linlaProgressBar.setVisibility(View.GONE);
}
If you are not using an AsyncTask, then set the visibility to View.VISIBLE at the start of the method where you start downloading the data and set it to View.GONE either after or just before you set the Adapter.
EDIT: Adding additional info.
Couple of things.
You are downloading data off the Internet for which, I would recommend switching to AsycnTask instead of using a conventional () Method.
Check out my answer a few days ago on a similar question here: https://stackoverflow.com/a/13265776/450534
In that answer, you will find a complete solution that will suit your exact needs. Well, almost entirely anyway. You may have to make a few modifications and adapt to a few things yourself. But by and large, it will answer all your questions. I use it in my apps and they function as you say, the Google Play loading text at the bottom. And it really is complete. :-)
You need to create custom view for that and inflate it and add as bottom view in gridview
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<Button android:text="Load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<ProgressBar
android:layout_width="25.0dip"
android:layout_height="25.0dip"
android:layout_centerInParent="true"
android:visibility="gone"
/>
</RelativeLayout>
now inflate this view and show the progressbar at bottom of gridview
You can set button as bottom with this when you click just visible the progressbar
Just add a ProgressBar in your layout, set its visibility to VISIBLE or GONE whenever you want to show/hide it.
Add a in the xml of GridView and set its property "alignParentRight = true" and "visibility = invisible" . In your activity , use Async task class and on its preExectue method set set its visibility to visible
pb.setVisibility(View.VISIBLE);
In doInBackground method load your images and finally in onPostExecute method make this progress bar invisible.
pb.setVisibility(View.INVISIBLE);
execute this async task class on click of load button.
This is an easy tutorial for understanding asyncTask
http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
Or threads can be used instead of async task.
When my Activity loads, I inflate a layout file that I use for a footer. I attach it to the ListView (addFooterView) and then set its visibility to View.GONE. I maintain a reference to it, and when I want the user to see it, I set the visibility to View.VISIBLE.
For the most part, this works great. However, the footer seems to still take up space. If the user uses the scroll wheel/pad, the area the footer is taking up gets highlighted. I'd like to polish this more so the footer is completely gone; ideally without detaching it from the ListView.
Is this possible? Or am I going to have to set/unset the foot instead of simply toggling its visibility?
You can use listView.removeFooterView(view). The easiest way to do this is to create an instance variable to hold your inflated footer view (so you only inflate it in onCreate() ). Then just call listView.addFooterView(instanceFooter) and listView.removeFooterView(instanceFooter) as needed.
Edit:
Here's what I'm doing to get this to work:
inflate footer layout(s) in onCreate
onResume: IF the adapter has not been instantiated, call addFooterView() THEN initialize your adapter (keep an instance reference to it) and call setAdapter(). This will leave the ListView "prepped"
onResume: update the adapter with the data (I have my data in a separate class) and call notifyDatasetChanged()
Call removeFooterView() (it will hide it if it's being displayed and do nothing otherwise)
Call addFooterView() if the footer needs to be displayed
You can toggle the visibility. To do that, you need to wrap the content of your footer using a linearlayout, then you set the linearlayout visibility to GONE.
In the example bellow I set the visibility of LogoLinearLayout to GONE and it worked.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/LogoLinearLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/Logo"
android:src="#drawable/Logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing3"
android:layout_marginBottom="#dimen/spacing3"
android:layout_gravity="center" />
</LinearLayout>
</LinearLayout>
Set isSelectable parameter to false when You call addFooterView to disable footer selection and highlighting
Try using View.INVISIBLE instead of View.GONE. (I have not tried this,but it might work)
I have Created a ListView and set a background image.Everything goes fine except I am unable to click on the right side of the row of ListView.Can anybody help me this.
Below is the xml file...
<ListView
android:layout_width="wrap_content"
android:id="#+id/JSONListView"
android:layout_height="wrap_content"
android:background="#drawable/listbg"
android:focusable="false"
android:cacheColorHint="#00000000"
android:visibility="visible" >
</ListView>
And I am not using any View.
Use the attribute
android:layout_width="match_parent"
and set click listener for items.
I guess you have created your custom adapter. If so, just go to the getView() method of that custom adapter and on the holder instance of that portion of listitem add a onCLickListener.
Provide more info. XML layout, etc.
Im guessing there is a view there or it is not filling the entire width but difficult to say.
Android ListView Activity