I have an empty view which I set via the ListView object that I have created. The issue that I'm facing is that even when the list is populated, the empty view is still shown and not the populated list view (I've tried removing the empty view and it works correctly).
Here's the code for the xml layout of the activity where I have the ListView and empty view(they're in a relative layout):
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/requests_list"
/>
<TextView
android:id="#+id/no_requests_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="No current requests"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:fontFamily="sans-serif-smallcaps"
android:visibility="gone"
/>
Here's how I set the empty view:
View emptyView = findViewById(R.id.no_requests_textView);
RequestAdapter requestAdapter = new RequestAdapter(this, requestDetailsArrayList);
ListView requestsListView = (ListView) findViewById(R.id.requests_list);
requestsListView.setAdapter(requestAdapter);
requestsListView.setEmptyView(emptyView);
Does anyone know what the issue is?
Thanks in advance!
try this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
<TextView
android:id="#+id/no_requests_textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:text="no request" >
</TextView>
TextView emptyView = findViewById(R.id.no_requests_textView);
if(requestDetailsArrayList.size()==0)
{
emptyView.setVisibility(View.VISIBLE);
ListView.setVisibility(View.GONE)
}
else
{
emptyView.setVisibility(View.GONE);
ListView.setVisibility(View.VISIBLE)
}
What you need to do is remove the emptyview from the main layout and make it in different layout and add following lines:
ViewGroup parentGroup = (ViewGroup) requestsListView.getParent();
View empty = getActivity().getLayoutInflater().inflate(R.layout.empty_view,
parentGroup,
false);
parentGroup.addView(empty);
requestsListView.setEmptyView(empty);
Related
I'm trying to create a layout that contains a ListView with a button underneath it, and also make it so that the button 'sticks' to the bottom of the ListView, even when I add or delete a row from the ListView.
With the layout code below, when I add a new row to the list, the button 'moves' to its correct location right beneath the bottom of the ListView. So that works fine.
The problem is when I delete a row from the ListView, the button stays where it is and doesn't 'move up' so that it sticks to the bottom of the ListView. When I rotate the device and it recreates the view, the button does in fact move up, but I'd like it to automatically move up when a row is deleted.
Here is the code I have now:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0" />
<ImageButton
android:id="#+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/add_button" />
</LinearLayout>
SOLUTION:
The solution was to create a small layout file that contains just the button, then add it as the footer of the ListView programatically.
Inside my fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
...
View footerView = inflater.inflate(R.layout.listview_footer, null, false);
addButton = (ImageButton) footerView.findViewById(R.id.addButton);
listView.addFooterView(footerView);
data = getListViewData();
adapter = new MyListAdapter(getActivity(), data);
listView.setAdapter(adapter);
...
}
listview_footer.xml:
<?xml version="1.0" encoding="utf-8"?>
<ImageButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/add_button" />
The listview_footer.xml just contains the button, and no layout.
Now, when I delete a row from the ListView, the button moves up to 'stick' to the bottom of the ListView. And as before, when I add a row to the ListView, the button moves down below it.
You can add button to the footer of the listview.
View footerView = View.inflate(this, R.layout.footer, null);
listview.addFooterView(footerView);
Make an xml file for the footer view in which you will add a button as per your UI needs.
Footer.xml may look like following:
<?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:padding="5dip">
<Button android:id="#+id/previous"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />
</RelativeLayout>
This link may be helpful for you.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="#+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below= "#+id/listView"
android:src="#drawable/add_button" />
</RelativeLayout>
I had a similar situation where I wanted a button to always be in the bottom right of my list, and there would be many deletion/additions to the list. I used a relative Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/search_bg" >
<ListView
android:id="#+id/list_searchfilters"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#android:color/transparent"
android:dividerHeight="10dp"
android:listSelector="#drawable/search_list_selector" />
<Button
android:id="#+id/add_filter_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:layout_below="#id/list_searchfilters"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp" />
</RelativeLayout>
And everytime a row would be deleted or added I would just call LayoutUtils.setListViewHeightBasedOnChildren(mSearchListView); which I had defined as :
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
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();
}
User RelativeLayout instead. Add android:layout_alignParentBottom="true" to Image Button and android:layout_above="#+id/addButton" to listView
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/addButton"
android:layout_alignParentTop="true"/>
<ImageButton
android:id="#+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/add_button"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
I am creating a Help page in which I have a set of questions and answers. These questions and answers have different styles. Here is the xml file, which describes the layout of a question & answer set:
<?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="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<TextView
android:text="#string/Help_first_question"
android:id="#+id/text1"
android:padding="5dip"
android:background="#e0f3ff"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/panel1"
android:visibility="gone"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_margin="2dip"
android:text="#string/Help_first_answer"
android:padding="5dip"
android:background="#FFFFFF"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
I want to display multiple questions and answers within a listView, whereby each row contains a set of the question and the answer. My listview looks like :
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
so it will look like :
first row : Q
A
second row : Q
A
third row : Q
A
What is the best approach for achieving this?
create custom adapter and use the below layout to achieve your goal
<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"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
You need to implement a custom ListAdapter implementing all of the abstract methods.
Let's create a QuestionAndAnswerListAdapter, which you can make your ListView by setting it up in onCreate:
public void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
setContentView(R.layout.listview);
QuestionsAndAnswersListAdapter adapter = new QuestionsAndAnswersListAdapter(data);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
}
The adapter itself would look something like this:
public QuestionsAndAnswersListAdapter implements ListAdapter {
private QuestionAndAnswer[] data;
public QuestionsAndAnswersListAdapter(QuestionAndAnswer[] data) {
this.data = data;
}
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
//Only creates new view when recycling isn't possible
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.question_and_answer_list_item, null);
}
QuestionAndAnswer thisQA = data[position];
TextView questionView = (TextView) view.findViewById(R.id.text1);
questionView.setText(thisQA.question);
TextView answerView = (TextView) view.findViewById(R.id.answer);
answerView.setText(thisQA.answer);
return view;
}
// ...
}
getView is really the central method to get right. The rest of the methods you need to implement to live up to the ListAdapter interface are pretty straight-forward. Check the reference to see exactly what they are.
I am having problems with ListView on android. I have an Activity with an EditText view and a button. The idea is user should enter some info in the EditText field, touch the Search button which retrieves a list from a web service that it is displayed in the same activity below the EditText and the Button. Everything fine, I got the data from Internet but items weren't displaying. I was using the notifyDataSetChanged(). After a couple of hours with no success, I decided trying to put some items manually and it turns out that again nothing was displayed, hence I think I am doing something wrong when I am trying to set the listview and the adapter. So here is the code..
the xml of the activity activity_search.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<EditText
android:id="#+id/edit_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:inputType="text"
android:hint="Enter info"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:drawable/ic_menu_search"
android:contentDescription="Search"
android:ems="10" />
</LinearLayout>
<ListView
android:id="#+id/listview_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false" />
The XML of the item row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="5dp">
<TextView
android:id="#+id/row_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Common_TextContent"
android:textAppearance="#android:style/TextAppearance.Holo.Medium" />
<TextView
android:id="#+id/row_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="#string/Common_TextContent"
android:textAppearance="#android:style/TextAppearance.Holo.Small" /></LinearLayout>
the custom Adapter:
public class ItemsListAdapter extends ArrayAdapter<ItemsList> {
private int[] colors = new int[] { 0x30ffffff, 0x30808080 };
public AssetListAdapter(Context context,
List<ItemsList> itemsList) {
super(context, 0, itemsList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, null);
}
convertView.setBackgroundColor(colors[position % colors.length]);
TextView code = (TextView) convertView.findViewById(R.id.row_code);
code.setText(getItem(position).getCode());
TextView name = (TextView) convertView.findViewById(R.id.row_name);
name.setText(getItem(position).getName());
return convertView;
}
and the onCreate method on the Activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
_listView = (ListView) findViewById(R.id.listview_items);
_listItems = new ArrayList<ItemsList>();
_listItems.add(new ItemsList ("cosa1", "cosa1", "cosa1", "cosa1"));
_listItems.add(new ItemsList ("cosa2", "cosa2", "cosa2", "cosa2"));
_listItems.add(new ItemsList ("cosa3", "cosa3", "cosa3", "cosa3"));
_adapter = new ItemsListAdapter(this, _listItems);
_listView.setAdapter(_adapter);
}
The ItemsList is just an Object with 4 strings with all the getters implemented.
When I debug in the getView method of the Adapter, the view (convertView) is created and it has the right information. It is just that is not showing those in the screen. What am I doing wrong?
Thanks...
Your second LinearLayout has a height of match_parent. Try wrap_content instead.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
How to use a layout as empty view for a listview when the adapter has zero elements?
setEmptyView is not working with this code :
public class ZeroItemListActivity extends Activity {
private ArrayList<String> listItems=new ArrayList<String>();
private ListView mMyListView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMyListView=(ListView) findViewById(R.id.MyListView);
mMyListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,listItems));
LayoutInflater inflator=getLayoutInflater();
View emptyView=inflator.inflate(R.layout.empty_list_item, null);
//Empty view is set here
mMyListView.setEmptyView(emptyView);
}
public void addItem(View v){
listItems.add("list Item");
mMyListView.invalidate();
}
}
Layouts used : empty_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:id="#+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Empty List,Click to add items"></Button>
</LinearLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="#string/hello" />
<ListView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/MyListView"></ListView>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/AddItemsButton"
android:text="Add Items" android:onClick="addItem"></Button>
</LinearLayout>
The easiest way to get this done is to put the empty view in the main.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<ListView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/MyListView">
</ListView>
<!-- empty view -->
<LinearLayout android:id="#+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button android:id="#+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Empty List,Click to add items">
</Button>
</LinearLayout>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/AddItemsButton"
android:text="Add Items"
android:onClick="addItem"></Button>
</LinearLayout>
Then, in your code, set your empty view like this:
mMyListView.setEmptyView(findViewById(R.id.emptyView));
The reason your code isn't working is that the ListView and Empty view need to be in the same view heirarchy. And your call to inflate pass null as the parent so they are in different heirarchies.
The Android Dev tutorial for List Activity covers this topic:
http://developer.android.com/reference/android/app/ListActivity.html
Basically have your class extend ListActivity. Set your list id to #id/android:listand the "empty view" id to #id/android:emptyin the same XML layout.
Hope this helps :)
When, inflating the view, you have to set the view parent to be part of the Layout hierarchy rather than pass null in some cases.
Replace
View emptyView = inflator.inflate(R.layout.empty_list_item, null);
with
View emptyView = inflator.inflate(R.layout.empty_list_item, (ViewGroup) mMyListView.getParent());
then you set the empty view as you did before with.
mMyListView.setEmptyView(findViewById(R.id.emptyView));
I have an app whose main class extends ListActivity:
public class GUIPrototype extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Cursor c = managedQuery(People.CONTENT_URI, null, null, null, null);
String[] from = new String[] {People.NAME};
int[] to = new int[] { R.id.row_entry };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,R.layout.drawer,c,from,to);
setListAdapter(adapter);
getListView().setTextFilterEnabled(true);
}
}
I have a sliding drawer included in my XML, and I'm trying to get a separate listview to appear in the sliding drawer. I'm trying to populate the second listview using an inflater:
View inflatedView = View.inflate(this, R.layout.main, null);
ListView namesLV = (ListView) inflatedView.findViewById(R.id.content);
String[] names2 = new String[] { "CS 345", "New Tag", "Untagged" };
ArrayAdapter<String> bb = new ArrayAdapter<String>(this, R.layout.main, R.id.row_entry, names2);
namesLV.setAdapter(bb);
This compiles, and runs, but the slidingdrawer is completely blank. My XML follows:
<SlidingDrawer
android:id="#+id/drawer"
android:handle="#+id/handle"
android:content="#+id/content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom">
<ImageView
android:id="#id/handle"
android:layout_width="48px"
android:layout_height="48px" android:background="#drawable/icon"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#id/content"/>
</SlidingDrawer>
I feel like I'm missing a vital step. I haven't found any resources on my problem by Googling, so any help would be greatly appreciated.
Edit: This was for a problem a long time ago, and the solution I found was to just redesign my layout. I am unable to accept an answer as I don't have the means to test them.
I Suppose I might have found the solution.
All these above solutions did not worked for me.
But then, what I did was add onClickListener to actual view which I return from adapter and BAM it started working for me.
Here is the sample code:
May layout XML (Not complete one....)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/details"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ScrollView
android:id = "#+id/scrolling"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:paddingBottom="30dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/listingIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
............
</ScrollView>
<SlidingDrawer
android:id="#+id/slidingDrawerShowMore"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:topOffset="132dip"
android:handle="#+id/handle"
android:content="#+id/content">
<LinearLayout
android:id="#+id/handle"
android:padding = "5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/black">
<TextView
android:id="#+id/title"
android:layout_alignParentRight="true"
android:textSize="14dp"
android:layout_below="#id/rate"
android:singleLine="true"
android:textColor="#3F48CC"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/show_more"/>
</LinearLayout>
<LinearLayout
android:id="#id/content"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:gravity="center"
android:background="#android:color/black">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_vertical"
android:background="#drawable/dark_header">
<TextView
android:id="#+id/otherTitle"
android:layout_alignParentRight="true"
android:layout_below="#id/rate"
android:singleLine="true"
android:textSize="21px"
android:paddingLeft="10px"
android:textColor="#EBEBEB"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="0.6"
android:text="#string/someString"/>
<ProgressBar
android:id="#+id/pbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#android:style/Widget.ProgressBar.Small"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
</SlidingDrawer>
</RelativeLayout>
Now to handle click events all I had to do was to add onClickListener in my adapter
public View getView(int position, View convertView, ViewGroup parent) {
convertView.setOnClickListener(this);
}
That's it. Problem is I could not get my onItemClickListener working for this ListView. But right now on click listener works for me. One day I would love to find out reason behind this.
It looks like the problem could be that you are inflating a new instance of a ListView rather than using the one in your view.
Try getting the ListView with ListView listView = (ListView) findViewById(R.id.content);
Then apply your adapter to it.
Have you tried
View inflatedView = View.inflate(this, R.layout.main, null);
SlidingDrawer sliding=(SlidingDrawer) inflatedView.findViewById(R.id.drawer);
ListView namesLV = (ListView) sliding.findViewById(R.id.content);