Creating ListView results in odd behaviour - android

I am trying to create a listView in my app. Such that only part of the screen will be used for the listView, and the other part will be used as permanent information. I get strange output, the listView instead of showing the required string, shows the permanent information.
Here is my code:
activity_main.xml
<!-- Start of the permanent information -->
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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.mti_student.kol_mila.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/header_image_id"
android:layout_width="100dp"
android:layout_height="90dp"
android:layout_marginBottom="0dp"
android:src="#drawable/logo"
android:layout_centerHorizontal="true"/>
<LinearLayout
android:id="#+id/search_panel_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/header_image_id"
android:orientation="vertical"
android:layoutDirection="rtl">
<TextView
android:id="#+id/text_view_id"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAlignment="center"
android:text="Title"
android:layout_marginBottom="5dp"/>
<SearchView
android:id="#+id/search_view_id"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:queryHint="Search"
android:iconifiedByDefault="false"
android:layout_gravity="center"
android:queryBackground="#color/colorWhite"
android:background="#color/colorPrimary" />
</LinearLayout>
<!-- End of permanent information -->
<!-- This where I want my list view to appear -->
<FrameLayout
android:id="#+id/fragment_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/search_panel_id"
android:background="#color/colorBeige"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<ListView android:id="#+id/list_view"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
</ListView>
</FrameLayout>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<String> filePaths = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyFromAssets();//Stores the information to filePaths
ListView lv = findViewById(R.id.list_view);
ArrayList<HashMap<String,String>> arrayList=new ArrayList<>();
for (int i=0;i<filePaths.size() ;i++)
{
HashMap<String,String> hashMap=new HashMap<>();//create a hashmap to store the data in key value pair
hashMap.put("file_name",filePaths.get(i));
arrayList.add(hashMap);//add the hashmap into arrayList
}
String[] from={"name"};
int[] to={R.id.topic_id};
SimpleAdapter simpleAdapter=new SimpleAdapter(this,arrayList,R.layout.activity_main,from,to);
lv.setAdapter(simpleAdapter);
}

You're using your main activity layout as the layout for each of the items rendered by the SimpleAdapter - see the third parameter of the constructor. Instead, provide the layout which contains the TextView with id topic_id, as per your setup prior to instantiating the SimpleAdapter.

Maybe it could be because you are using the same resource as your main activity to display the information in your list view
activity:
SetContentView(R.layout.activity_main);
you should use your own view for the list view to inflate
SimpleAdapter simpleAdapter=new simpleAdapter(this,arrayList,*R.layout.row*,from,to)

Related

TextView with wrap_content height obscured by ListView below it

I am not seeing my "Hello World" textview.
The listview, which I populate with elements, is all that shows.
<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">
tools:context="lister.quantumproductions.com.lister.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_above="#+id/recipe_list_view"></TextView>
<ListView
android:id="#+id/recipe_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</RelativeLayout>
public class MainActivity extends AppCompatActivity {
private ListView mListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadListView();
}
private void loadListView() {
mListView = findViewById(R.id.recipe_list_view);
final ArrayList<Recipe> recipes = Recipe.getRecipesFromFile("recipes.json", this);
RecipeAdapter a = new RecipeAdapter(this, recipes);
mListView.setAdapter(a);
}
}
Your ListView fills the entire screen, and then you say that the TextView should be above the ListView, which makes it appear outside the screen, so it's not visible.
You need to invert the dependency.
So instead of the TextView being above the ListView, the ListView should be below the TextView.
RelativeLayout causes the last item covers the previous one if it has match_parent width and height. Change the order or use LinearLayout instead of.
you can use LinearLayout as the parent with Vertical Orientation it will work perfectly:-
I have corrected your xml code , use this code it works
<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="lister.quantumproductions.com.lister.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_above="#+id/recipe_list_view"></TextView>
<ListView
android:id="#+id/recipe_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
it will work and both textview and listview will be shown .
incase you want to use relative layout only just make listview also wrap_content
<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">
tools:context="lister.quantumproductions.com.lister.MainActivity">
<TextView
android:id="#+id/recipe_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"></TextView>
<ListView
android:id="#+id/recipe_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/recipe_text_view"></ListView>
</RelativeLayout>
try this
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"></TextView>
<ListView
android:layout_below="#id/text_view"
android:id="#+id/recipe_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>

cannot show listView on fragment

I have a xml Layout file (ListLayout.xml) where i create listView and i want this layout to be shown on a fragment on main_activity_layout. so go to MainActivity_layout and i added a fragment , when it is proposed to choose a class i choosed the class Listfrg where i return the layout of listLayout.xml within OnCreateView methode , but nothing is shown why ?
ListLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/progress_container_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone" >
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<FrameLayout
android:id="#+id/list_container_id"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/empty_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false" >
</ListView>
</FrameLayout>
</FrameLayout>
MainActivityLayout
<fragment
android:layout_width="162dp"
android:layout_height="match_parent"
android:name="com.example.pack2.t9ahbin.Listfrg"
android:id="#+id/fragment3" />
Class Listfrg :
public class Listfrg extends ListFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frglist, container, false);
return view;
}
}
nothing is shown why?
Because there is no data in your list.
Please use an ArrayAdapter or some Adapter variant, put some data into it with adapter.add, and the use listView.setAdapter. To actually give data to your Listview.
You can do this in onCreateView and use getListView() or this to get the ListView.
ListView listView = (ListView) view.findViewById(android.R.id.list);
An Adapter is the data container for a ListView. Without one, how do you expect to display data?
Also your empty view needs to use android:id="#android:id/empty"
This is all well covered in AdapterViews

Listview dynamically allocate width

I want to allow my ListView to be wrapped to its content on its width and making it aligning to the parent centre.
This is what a normal ListView is giving me
This is almost what i want to achieve, only that i want the ListView to wrap by the longest test in the ListView. Currently this is achieved by declaring the dp which is something I would like to avoid if possible
Some codes for first image:
<ListView
android:id="#+id/lst_test"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content" >
</ListView>
Some codes for second image:
<ListView
android:id="#+id/lst_test"
android:layout_width="200dp"
android:layout_height="wrap_content" >
</ListView>
Do I have to use custom adapter for this or I can stick with the current one? If I would need to use custom adapter, how do i go about doing this?
You don't need to create custom adapter. Here is an example which can help you.
public class MainActivity extends Activity {
HashMap <String, CheckBox> options = new HashMap<String, CheckBox>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list_view = (ListView) findViewById(R.id.listView1);
ArrayList<String> str = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
str.add("Example " + i);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_layout, R.id.textView1, str);
list_view.setAdapter(adapter);
}
}
Above I have created an activity in which i am getting listview and setting data using ArrayAdapter.
I have created two layouts :
First layout: Contains listview.
Second layout: Contains textview which need to display.
Main logic to align data at center of Listview is you need to set gravity of textview as center.
You can manage second layout according to your needs.
Here is my first XML layout:
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
Here is my second layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="TextView" />
</RelativeLayout>
If you are still facing any problem then you can ask. If you need more flexibility then you can create custom adapter by inheriting ArrayAdapter class.
Here is an example of custom adapter: How do I link a checkbox for every contact in populated listview?
Hope it will help you.

Set default ListView

Is there any way to change the ListView in a SherlockListFragment from defaulting to R.id.list? e.g. I have a custom list that overrides the default ListView in xml (list) that is defined as being below a linear layout. How do I make it so that setListAdapter will use this ListView instead of the default android ListView?
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_view_panel"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/toggleLL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<ToggleButton
android:id="#+id/toggle_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ToggleButton
android:id="#+id/toggle_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ToggleButton
android:id="#+id/toggle_button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toggleLL" />
</RelativeLayout>
Fragment:
public class ProblemFragment extends SherlockListFragment
{
private SeparatedListAdapter list;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.getSherlockActivity().setContentView(R.layout.apps_layout);
list = new SeparatedListAdapter(this.getSherlockActivity(), new Layout(R.layout.separated_list_adapter_two_text, R.id.two_text_title, R.id.two_text_desc));
setListAdapter(list); //Sets the list to the default list, not the overwritten list specified in the xml
}
}
Just change your layout XML to use android:id="#android:id/list".
ListActivity and ListFragment rely on the ListView having the id android.R.id.list, which is publicly exposed in the SDK (and accessible in XML via #android:id/list). If you look at the docs for either of those classes, both mention that using your own layout requires that you give your ListView this id for it to work properly.

Showing empty view when ListView is empty

For some reason the empty view, a TextView in this case, always appears even when the ListView is not empty. I thought the ListView would automatically detect when to show the empty view.
<RelativeLayout android:id="#+id/LinearLayoutAR"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<ListView android:id="#+id/ARListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"></ListView>
<ProgressBar android:id="#+id/arProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"></ProgressBar>
<!-- Here is the view to show if the list is emtpy -->
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
</RelativeLayout>
How can I hook up the empty view properly?
When you extend FragmentActivity or Activity and not ListActivity, you'll want to take a look at:
ListView.setEmptyView()
It should be like this:
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
Note the id attribute.
As appsthatmatter says, in the layout something like:
<ListView android:id="#+id/listView" ... />
<TextView android:id="#+id/emptyElement" ... />
and in the linked Activity:
this.listView = (ListView) findViewById(R.id.listView);
this.listView.setEmptyView(findViewById(R.id.emptyElement));
Does also work with a GridView...
I tried all the above solutions.I came up solving the issue.Here I am posting the full solution.
The xml file:
<RelativeLayout
android:id="#+id/header_main_page_clist1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:paddingBottom="10dp"
android:background="#ffffff" >
<ListView
android:id="#+id/lv_msglist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/divider_color"
android:dividerHeight="1dp" />
<TextView
android:id="#+id/emptyElement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="NO MESSAGES AVAILABLE!"
android:textColor="#525252"
android:textSize="19.0sp"
android:visibility="gone" />
</RelativeLayout>
The textView ("#+id/emptyElement") is the placeholder for the empty listview.
Here is the code for java page:
lvmessage=(ListView)findViewById(R.id.lv_msglist);
lvmessage.setAdapter(adapter);
lvmessage.setEmptyView(findViewById(R.id.emptyElement));
Remember to place the emptyView after binding the adapter to listview.Mine was not working for first time and after I moved the setEmptyView after the setAdapter it is now working.
Output:
I highly recommend you to use ViewStubs like this
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ViewStub
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout="#layout/empty" />
</FrameLayout>
See the full example from Cyril Mottier
<ListView android:id="#+id/listView" ... />
<TextView android:id="#+id/empty" ... />
and in the linked Activity:
this.listView = (ListView) findViewById(R.id.listView);
this.listView.setEmptyView(findViewById(R.id.empty));
This works clearly with FragmentActivity if you are using the support library. Tested this by building for API 17 i.e. 4.2.2 image.
Activity code, its important to extend ListActivity.
package com.example.mylistactivity;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import com.example.mylistactivity.R;
// It's important to extend ListActivity rather than Activity
public class MyListActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylist);
// shows list view
String[] values = new String[] { "foo", "bar" };
// shows empty view
values = new String[] { };
setListAdapter(new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
android.R.id.text1,
values));
}
}
Layout xml, the id in both views are important.
<?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">
<!-- the android:id is important -->
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<!-- the android:id is important -->
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="i am empty"/>
</LinearLayout>
Just to add that you don't really need to create new IDs, something like the following will work.
In the layout:
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/empty"
android:text="Empty"/>
Then in the activity:
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setEmptyView(findViewById(android.R.id.empty));
I had this problem. I had to make my class extend ListActivity rather than Activity, and rename my list in the XML to android:id="#android:id/list"
A programmatically solution will be:
TextView textView = new TextView(context);
textView.setId(android.R.id.empty);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setText("No result found");
listView.setEmptyView(textView);
First check the list contains some values:
if (list.isEmpty()) {
listview.setVisibility(View.GONE);
}
If it is then OK, otherwise use:
else {
listview.setVisibility(View.VISIBLE);
}

Categories

Resources