I've created a simple app that sends a search term to a php script, reads the json response generated by that php script based on the search term, processes the json response and loads the json nodes values in a listview. All goes well, the search is completed, the json gets processed, the values are loaded in the listview.
I have just one problem with the listview: each item is on a different screen.
This is my xml with the listview, called listview1.xml:
<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:background="#drawable/background"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:text="#string/app_mresults"
android:textColor="#color/text_color" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
tools:listitem="#android:layout/simple_list_item_1" >
</ListView>
</LinearLayout>
And this is the xml for each item, called listview1row.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background"
android:orientation="vertical" >
<TextView
android:id="#+id/ref_pnr"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/ref_partnumber"
android:textColor="#color/text_color" />
<TextView
android:id="#+id/ref_pname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ref_part"
android:textColor="#color/text_color" />
<TextView
android:id="#+id/ref_supp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ref_supplier"
android:textColor="#color/text_color" />
<TextView
android:id="#+id/ref_avail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ref_available"
android:textColor="#color/text_color" />
</LinearLayout>
What am i doing wrong? I've played with the layout width and height and with the layout of the listview, and nothing. Is there a specific combination of width and height i must use?
I've looked into some listview tutorials on some websites, copied the layout details from there and still nothing. I've looked at the json response and it does not contain any breaklines or carriage returns.
Edit: Below is the part where i set the adapter for the ListView.
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
Reference2.this, productsList,
R.layout.activity_reference3, new String[] { TAG_PNR,
TAG_PNAME, TAG_PSUPP, TAG_PAVAIL},
new int[] { R.id.ref_pnr, R.id.ref_pname, R.id.ref_supp, R.id.ref_avail });
// updating listview
setListAdapter(adapter);
}
});
}
i think, because you are using ListView, you should look at LayoutInflater to load the list values.
Here is an example on how to achieve it using LayoutInflater: http://www.mysamplecode.com/2011/10/android-dynamic-layout-using-xml-add.html
Since you are using linearLayout in your list item use layout_weight attribute on items based on your need.
I have finally found what the problem was.
I was using android:background="#drawable/background". Once removed, everything worked as it should.
I came across this while i was rebuilding the listview1row.xml by hand instead of using the visual editor.
Thank you all for the answers and help!
Related
I have a three tab interface setup using a ViewPager. In the 3rd tab, I have a CardView which can expand/retract onclick to reveal more information. Inside the CardView is a RecyclerView which is inflated with a bunch of data.
The first time the app opens and the CardView is expanded, the expand animation is quite laggy but afterwards, it can be expanded/retracted smoothly. The RecyclerView data can also be updated with no problem.
Is there a way to somehow load/cache the data upon opening the app so the lagg does not occur.
Sorry if question is poor, just starting android development.
Thanks
Layout on third tab:
<android.support.v7.widget.CardView
android:id="#+id/SF_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<LinearLayout
android:id="#+id/SF_wrapper"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/SF_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</android.support.v7.widget.CardView>
The data which is used to inflate the recyclerView is a list of objects each with 2 float variables. Roughly length ~50.
The xml used to inflate each item:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4sp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="36sp"
android:layout_weight="1">
<TextView
android:id="#+id/value_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="lorem"
android:textSize="8sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="36sp"
android:layout_weight="1">
<TextView
android:id="#+id/value_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="ipsom"
android:textSize="8sp" />
</RelativeLayout>
</LinearLayout>
The code to expand/retract the cardView simply animated changing the height of SF_frame to reveal more elements of the RecyclerView and it is this first reveal which is laggy.
Resolve your Layouting as first:
Use sp only with texts and dp for other dimensions (width, height, margins, paddings etc.). For texts it is recommended to use at least android:textsize="12sp". Look at the android:gravity attribute instead of android:layout_gravity so you don't have to use parent layout just to center it.
<android.support.v7.widget.CardView
android:id="#+id/SF_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<!-- No need to use LinearLayout since only one child is used -->
<android.support.v7.widget.RecyclerView
android:id="#+id/SF_list"
android:layout_width="match_parent"
android:layout_height="80dp">
</android.support.v7.widget.RecyclerView>
</android.support.v7.widget.CardView>
In this layout, if you are expanding RecyclerView, it is possible that new views are being instantiated (RecyclerView.Adapter.onCreateViewHolder and RecyclerView.Adapter.onBindViewHolder) are called mulitple times.
In fact switching to that Tab is also a little bit delayed, but it is clearly visible on animation. (you are expandig from about 3 items to maybe 20 or so, I don't know how rest of your layout looks)
and second:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:orientation="horizontal">
<TextView
android:id="#+id/value_1"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_weight="1"
android:layout_gravity="center"
android:text="lorem"
android:textSize="8sp" />
<TextView
android:id="#+id/value_2"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_weight="1"
android:layout_gravity="center"
android:text="ipsom"
android:textSize="8sp" />
</LinearLayout>
If filling these 2 TextViews is so terribly slow, that you are experiencing hickups. Then you probably doing very very complex math operations (try to simplify them if possible) or you are somehow downloading data synchronously and waiting for results.
Please have a look at AsyncTask and use it while binding data... You can use it something like this (modify by yourself):
private class MyAsyncTask extends AsyncTask<Void, Void, String> {
private TextView view;
MyAsyncTask(TextView view) {
this.view = view;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// display progressbar or something
}
#Override
protected String doInBackground(Void... params) {
// do heavyweight operation here
String result = heavyWeightOperation(params);
return result;
}
#Override
protected void onPostExecute(String s) {
// hide progressbar or something
if (view != null) {
view.setText(s);
}
super.onPostExecute(s);
}
}
I had set up an Activity and a Fragment, and in the layout I had a ListView, which I gave an arbitrary name and accessed via findViewById(). All was working fine, until I noticed that scrolling didn't work for the ListView.
There are many threads here on SO about ListView and lack of scrolling. I used much more time than I care to admit trying out one possible solution after another. Nothing worked, until I stumbled upon the solution, which I'll describe in an answer to this question.
EDIT:
I've deleted the answer I posted to my own question, where I claimed that you had to use ListFragment (or SherlockListFragment) to get scrolling of a ListView to work.
Thanks to Zackehh9lives I've determined that I was wrong in that claim.
The key phrase in his answer is that the stump of code he shows is in the onCreateView() method. After some experimenting, I think the situation is as follows:
If you use ListFragment (or SherlockListFragment) you have to set up the ListView widget in the onActivityCreated() method, and ListView scrolling works.
If you use Fragment (or SherlockFragment) you can set up ListView in onActivityCreated() or in onCreateView(), but if you do it in onActivityCreated() then scrolling doesn't work.
That was my problem - I was using SherlockFragment and setting up ListView in onActivityCreated().
I have a ListView in a SherlockFragment and it scrolls just fine. Not sure what the issue is? Perhaps you just have a something incorrect somewhere (might want to post your code?). Below is my ListView and XML:
MyFragment.java:
// Find the ListView we're using
list = (ListView)view.findViewById(R.id.listView);
// Set the vertical edges to fade when scrolling
list.setVerticalFadingEdgeEnabled(true);
// Create a new adapter
adapter = new ArrayAdapter<String>(getActivity(), R.layout.list_item, R.id.title, questions);
// Set the adapter to the list
list.setAdapter(adapter);
// Set on item click listener to the ListView
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// Do stuff
}
});
All that code is all I have related to my ListView in the Fragment, and it's in my onCreateView(). Below is the XML for it.
ListItem.xml:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_toLeftOf="#+id/arrow"
android:orientation="vertical" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/title"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/title"
android:layout_alignParentBottom="true"
android:layout_below="#+id/title"
android:layout_marginTop="5dp"
android:padding="2dp"
android:text="#string/date"
android:textColor="#7F7F7F"
android:textSize="12sp" />
</RelativeLayout>
<ImageView
android:id="#+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:contentDescription="#string/app_name"
android:src="#drawable/arrow_next" />
ListView.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="false"
android:paddingTop="-2dp" >
<ListView
android:id="#+id/listView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ListView>
</LinearLayout>
If you post your code, we have a better chance at helping :)
I would like to create a listview that allows multiple choice. The typical solutions is to get a cursor and use the SimpleCursorAdapter.
SimpleCursorAdapter adapter2 = new SimpleCursorAdapter(this,
R.layout.simple_list_item_multiple_choice, cur2, cols2, views2);
I am able to get this working when using the R.layout.simple_list_item_multiple_choice. I get the checkmarks to work when multiple items are selected.
So I decided to try it with a custom made layout. Here is the XML code for my layout.
<?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="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/lookup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/hasphone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<CheckedTextView
android:id="#+id/checkedTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"/>
</LinearLayout>
So here is my issue. The layout is inflated fine using the same code and setting the ChoiceMode to multiple on my listview. The data from the cursor is populated fine.
However, the issue I have is that the checkmarks do not show up as selected (a check in the box) when I click on the item. Is there something I am missing that would not involve creating a custom adapter?
l2.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
l2 is my listview.
I'm not up on CheckedTextView... from my understanding, it should toggle the check when you click the line.
I suppose you could try and force it like this:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
CheckedTextView chkTxt = (CheckedTextView) v.findViewById(R.id.CheckedTextView1);
chkTxt.toggle();
}
Note this would be a hack and you should really find the root problem, but it might get you going in the meantime.
EDIT
After much googling, I found the issue... the root of the row layout needs to be checkable to use CheckedTextView, and a LinearLayout is not.
More googling found a solution... override the LinearLayout class.
Instructions/code here
The problem with "the issue I have is that the checkmarks do not show up as selected" is because of your wrong layout. It should be without LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/lookup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/hasphone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<CheckedTextView
android:id="#+id/checkedTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkMark="?android:attr/listChoiceIndicatorMultiple" />
Then the SimpleCursorAdapter can set properly your "checkedTextView1" (with visible effect).
In my case I used the ArrayAdapter and it worked.
list.setAdapter(new ArrayAdapter<String>(this, R.layout.category_layout,
R.id.category_checkedText, this.categories));
I have a listView that I want to dynamically add data to.
here's the XML I want to add the data to.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/rowTextView"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:padding="12dp"
android:textSize="16sp" >
</TextView>
<TextView android:id="#+id/alarm_name_text"
android:layout_height="wrap_content"
android:text=""
android:layout_below="#+id/rowTextView"
android:layout_width="fill_parent">
</TextView>
<CheckBox android:id="#+id/CheckBox01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentRight="true" android:layout_marginRight="6sp"
android:focusable="false">
</CheckBox>
</RelativeLayout>
I want to add data to the 2nd TextView with the id alarm_name_text after a user has entered some data in an editText dialogView. I've been told to make a function that adds the data the my ArrayList/adapter but I'm not sure when to call it or how it's being used.. I needs help plz :(. Here's the function.
public void addItems(View v)
{
rowSavedText.setText(getString());
planetList.add(new Planet("This one"));
listAdapter.notifyDataSetChanged();
}
You'll need to work on the part of the code that renders the individual rows. Take a look at the tutorial at http://geekswithblogs.net/bosuch/archive/2011/01/31/android---create-a-custom-multi-line-listview-bound-to-an.aspx: specifically how it uses getView.
Just add the element to your ArrayList and call notifyDataSetChanged() to your array adapter.
I can't fill a ListView layout with an array of strings. Here is the Activity:
ListView symptomList = (ListView) findViewById(R.id.ListView_Symptom);
String symptomsArray[] = new String[1024];
// Then I fill up symptomsArray
ArrayAdapter<String> adapt = new ArrayAdapter<String>(this, R.layout.menu_item, symptomsArray);
symptomList.setAdapter(adapt);
Here is menu_item:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:textSize="#dimen/menu_item_size"
android:text="test string"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:shadowRadius="5"
android:gravity="center"
android:shadowDy="3"
android:shadowDx="3" />
And here is symptom.xml -
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_height="wrap_content"
android:id="#+id/ListView_Symptom"
android:layout_width="fill_parent"
android:divider="#drawable/divider"
android:listSelector="#drawable/textured"
android:layout_alignParentTop="true"></ListView>
</LinearLayout>
Does anyone have any idea what is wrong? Does my public class need to extend "ListActivity". I tried that and that didn't work.
Try stripping out some of the presentational bits from your TextView. For example, I don't think that you want android:layout_gravity="center" there. Also, try setting your ListView's android:layout_height="fill_parent".
Turns out Eclipse is so slow running on my 5 GB Dram MacPro that it eventually worked and displayed the array in the ListView, it just took a few minutes! Sorry about the confusion.