Can't remove or hide a view in Android - android

I'm trying to remove a progress indicator after loading my data in a fragment involving a ListView. Here is my completion handler:
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
dataSource = (ArrayList<Map<String, Object>>) task.getResult();
PostAdapter adapter = new PostAdapter(getActivity(), dataSource);
ListView list = (ListView) rootView.findViewById(R.id.listView);
list.setAdapter(adapter);
View indicator = getActivity().findViewById(R.id.indicator);
RelativeLayout layout = (RelativeLayout) getActivity().findViewById(R.id.layout);
layout.removeView(indicator);
}
});
The last 3 lines of code is the relevant part. Everything is called correctly, nothing is null etc. in debug everything works perfectly. The adapter also works correctly, populating my list, but the indicator is still on the screen. I've also tried setting it's visibility to GONE or HIDDEN but they also don't seem to hide it either. I've seen Android - Can't hide progress bar but it's answers involve setEmptyView() which I'm not using anyway. I am using the same fragment (of course, a different instance) in another tab, and it works correctly.
Here is my layout file:
<RelativeLayout 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:padding="0dp"
android:background="#ffffffff"
android:id="#+id/layout">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"
android:layout_margin="0dp"
android:padding="0dp" />
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/indicator"
android:indeterminate="true"
android:layout_centerInParent="true" />
</RelativeLayout>
What am I doing wrong?

I've found out the problem (thanks to all the commenters). I was calling activity's methods to find and remove the view. The problem is that, I have multiple instances of the same fragment in the same activity, under different tabs. I've used my fragment's root view to find and remove the indicator, instead of the activity, and it worked.

Change the codes of last three lines in onClick(...) as:
View indicator = (ProgressBar)rootView.findViewById(R.id.indicator);
and use:
indicator.setVisibility(ProgressBar.GONE);
or codes:
RelativeLayout layout = (RelativeLayout) rootView.findViewById(R.id.layout);
layout.removeView(indicator);

Related

ListView doesn't show any added items

I'm trying to add some items to ListView - they aren't showing.
I realize this question has been asked many times, but I tried to follow any advice I found there - none worked for me.
Here is content of my onCreate method of public class MyListActivity extends AppCompatActivity ->
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
((EditText) findViewById(R.id.editText2)).setInputType(InputType.TYPE_NULL);
ListView view = (ListView) findViewById(R.id.myList);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
view.setAdapter(adapter);
adapter.add("aaaaa");
adapter.add("bbbbb");
adapter.notifyDataSetChanged();
And here's my associated layout XML ->
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.kuba.myapplication3.MyListActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/background_dark"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="#string/txt_searching"
android:textColor="#android:color/white" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ButtonTxt" />
</LinearLayout>
<ListView
android:id="#+id/myList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:dividerHeight="1dp" />
</LinearLayout>
Well and like I said, "aaaa" and "bbbb" don't show anywhere.
Thanks in advance for any advice!
Your activity code is perfect. The problem is in your layout file and very silly one.
You set your main LinearLayout background as background_dark. And your ListView Text color is also dark. So it is not visible.
Try background color as background_light and your ListView will be visible.
Or, If you want to change ListView Text Color then do as following:
1) Create a Custom Layout as below : (custom_list_layout.xml)
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tvlist"
android:textColor="#color/white"
android:layout_width="fill_parent"
android:gravity="center"
android:layout_height="fill_parent"/>
2) Set this to your Array Adapter:
adapter = new ArrayAdapter<>(this, android.R.layout.custom_list_layout);
Then your ListView with white text will be visible in dark background. Hope this helps.
I see you are initializing the adapter without a reference to its set of items and it may be the problem. Please try this code instead:
Class field:
private List<String> items;
onCreate method:
...
items = new ArrayList<>();
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items);
view.setAdapter(adapter);
items.add("aaaaa");
items.add("bbbbb");
adapter.notifyDataSetChanged();
...
Or you could simply initialize the items list with the two elements instead of adding them later.
I'm not sure, but i think that sometimes UI elements modifications may be executed on another threads. Therefore, maybe when you add elements then notifyDataSetChanged(), views are not shown neither displayed yet, therefore, nothing is done. Then the adapter try to display something and has no elements.
I'g suggest two things :
-First, try to add elements to adapter list (like Juan Martinez answer) BEFORE adapter declaration and setAdapter(adapter);. Then create your adapter, set adapter.
-Second, try to add elements and notifyDataSetChanged on "onStart" instead of "onCreate()".
First test will allow you to see if the problem is in constructors, threads, etc. Second test will show you if you can add elements a little later in order to have things working if first test shows that you cannot add elements immediatly after "setAdapter".
It seems that your code is made for example or little tests, so, without knowing where you really need add objects and what is the display problem it may be hard to give you precise code.
on Oncreate method :
items = new ArrayList<>();
items.add("aaaaa");
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items);
view.setAdapter(adapter);
items.add("bbbbb");
adapter.notifyDataSetChanged();
Override onStart too
#Override
public void onStart() {
super.onStart();
adapter.add("cccc");
adapter.notifyDataSetChanged();
}
if your view shows only aaaa and cccc, then you cannot add items just after setAdapter. If nothing still show, the problem is somewhere else.

ActionBar Navigation Tabs - Main Activity Layout for Tab?

I have great problems getting the Navigation Tabs work. I am aware of this guide http://developer.android.com/guide/topics/ui/actionbar.html#Tabs
but I have problems understanding the article. It says the following:
To get started, your layout must include a ViewGroup in which you place each Fragment associated with a tab. Be sure the ViewGroup has a resource ID so you can reference it from your code and swap the tabs within it. Alternatively, if the tab content will fill the activity layout, then your activity doesn't need a layout at all (you don't even need to call setContentView()). Instead, you can place each fragment in the default root view, which you can refer to with the android.R.id.content ID.
As I don't use a Fragment for my Main Layout, but for others, I think the "alternative" way is right for me (I would like Tab 1 to be the Main Layout I have right now and then 2 and 3 to be my fragments), but I don't know how to accomplish this. Can someone maybe help out on this?
I was able to set up the tabs and the TabListener, so that is not the problem. The problem is that the first tab is NOT supposed to be a fragment, but my main activity layout! This is where I need help!
I did try to use my main activity-layout for a fragment, but for some reason if I click that tab, the tab changes but the screen stays white. I cannot see my fragment view.
The old code was:
mListView = (ListView) findViewById(R.id.list_view);
mListView.setAdapter(mAdapter);
mListView.setTextFilterEnabled(true);
and I've changed it in the fragment to:
View view = inflater.inflate(R.layout.list, container, false);
mListView = (ListView) view.findViewById(R.id.list_view);
mListView.setAdapter(mAdapter);
mListView.setTextFilterEnabled(true);
// do stuff here //
return view;
and this is list.xml:
<FrameLayout xmlns:android:="http://schemas.android.com/apk/res/android"
android:id="#id/main_fragment"
android:layout_width="match_parent"
android:layout:height=match_parent">
<ListView android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout:height=0dp"
android:layout_weight="1"
android:layout:marginTop="20dp"
android:descendantFocusability="blocksDescendants"/>
</FrameLayout>
how come I cannot see anything?
Solved: This was because I set the height to 0dp.
Please update your code by this:
<FrameLayout xmlns:android:="http://schemas.android.com/apk/res/android"
android:id="#+id/main_fragment"
android:layout_width="match_parent"
android:layout:height=match_parent">
<ListView android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:descendantFocusability="blocksDescendants"/>
</FrameLayout>

Android: ListFragment: How to refresh list

I have a list view which is shown on a fragment. I have a button at the bottom of the screen in which when pressed, will call a webservice to reteive any additional data. If there is additional data, I need to add it to the list view. I have searched this forum and so many other web sites to try and find how to do it, but I have had no success. Any help is much appreciated.
I am now thinking do I need to add the fragment dyncamically instead of having it defined on the following XML layout.
I am using a ListFragment to inflate a list view on the screen.
I have a screen with two fragments on it. The XML for the screen is below: -
<LinearLayout 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:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
<fragment
android:name="atos.mobilereporting.com.ReportList"
android:layout_width="323dp"
android:layout_height="match_parent" />
<fragment
android:name="atos.mobilereporting.com.ReportDetail"
android:layout_width="958dp"
android:layout_height="match_parent" />
</LinearLayout>
<Button
android:id="#+id/getReports"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh Mobile Reports" />
</LinearLayout>
The code to inflate the view is below: -
public class ReportList extends ListFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get list of reports...
repList = ReportDefinitionFactory.buildReportList(3);
activity = getActivity();
ListAdapter la = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1,
ReportDefinitionFactory.getReportDescriptions(repList));
setListAdapter(la);
}
}
This code shows a simple list view with 3 rows on it.
It is at this point I must stop as I do not know were to go from here. I have the code which will add an additional row to the array that is used to initially build the list view, but I do not know how I can invoke a refresh on the list view.
Thanks
Martin
You need to call la.notifyDataSetChanged() to force refresh of the list once the data has changed.
Use the ArrayAdapter notifyDataSetChanged() function.
This could be added in the ArrayAdapter, if that is the location where the data is updated. Otherwise, add it to the same area that calls la.add().

Inflating a View Inside a Runnable

I am attempting to write code that would allow me to have 1-2 views at the top of a listview that are of a different arrangement than the other views in the listview. I decided to try the method of using addHeaderView() for the 1-2 views that will differ in display.
I have two xml layout files, one that defines the view format that most of the listview views will fall under (list_image_checkbox_row.xml) and one for the Header Views (catalog_featured_row.xml). The adapter constructor uses list_image_checkbox_row as its resource in the constructor.
I used a Thread to set the adapter and load the views. I am able to programmatically create views and use addHeaderView to at them to the listview (using the same image resource), but I get errors when I try to use addHeaderView on a view I have inflated from a layout xml file.
handler.post(new Runnable() {
#Override
public void run() {
lv = (ListView)findViewById(R.id.sources_list);
Activity context = BrowseSourceActivity.this;
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.catalog_featured_row, null);
ImageView feat_view = (ImageView) view.findViewById(R.id.image);
feat_view.setImageResource(R.drawable.arrow);
lv.addHeaderView(feat_view);
setListAdapter(array);
}
});
I get a force close error and haven't been able to find anything in logcat (when I was trying to debug yesterday I got a NullPointerException). If I comment out the lv.addHeaderView(feat_view) line, the application does not force close on me. Here is the code for featured_catalog_row.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="70dip"
android:padding="5dip">
<ProgressBar android:id="#+id/spinner"
android:indeterminate="true"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_centerInParent="true"
/>
<ImageView android:id="#+id/image"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Any suggestions for how to get the inflater to work?
Perhaps you should store lv in an instance variable instead of looking it up dynamically. Note that both View and Activity have a method called findViewById, and so your results will depend on how your code is organized.

Custom Listview Adapter, adding a static footer, and understanding R.id.list

There is something I'm just not getting, and I'm looking for assistance in understanding what is happening here.
I have a custom list adapter (that just extends BaseAdapter) that I have successfully been using to generate and display a list. Now I want to add a static footer to the bottom of my list. After looking at a number of resources (specifically this one) I've come to realize that my reluctance of using XML has to come to an end, and set up the following xml layout in a file called devices_list.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:orientation="vertical">
<LinearLayout android:id="#+id/bottom_control_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<ToggleButton android:id="#+id/bottom_control_toggle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textOff="Filter Favourites OFF"
android:textOn="Filter Favourites ON"/>
</LinearLayout>
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_above="#id/bottom_control_bar">
</ListView>
<TextView android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/main_empty_list"
android:layout_above="#id/bottom_control_bar"/>
</RelativeLayout>
After some adjustments to the activity that holds the list, I ran the code. I see my footer, (and also the tab widget which is parent to everything), but the area where the list goes is empty.
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setContentView(R.layout.devices_list);
db = new DbManager(this);
db.open();
AllCur = db.fetchAllDevices();
startManagingCursor(AllCur);
list = new DeviceListAdapter(this, AllCur); //make my custom list adapter
setListAdapter(list);
}
Is there some way to link up the ListView widget declared in my xml with my DeviceListAdapter? It's pretty clear to me now that I'm not entirely sure about how this is all working. Any help in clarification would be much appreciated.
You have both the ListView and the TextView set to android:layout_above="#id/bottom_control_bar", which means the TextView will overlap the ListView. And, you have said that your ListView height is 0dip, which will make for an extremely short list.
I would define the ListView as being above the TextView and anchored to the top of the screen (android:layout_alignParentTop="true").
Is there some way to link up the
ListView widget declared in my xml
with my DeviceListAdapter?
You already are, by calling setListAdapter().

Categories

Resources