What to use to put layout in activity Android? - android

I have an activity that uses setContentView to initiate a listview, and then I have an If-Else condition. In the If part of the statement I use a simpleAdapter to place a new layout in the listview and other data from a cursor. In the Else part, I just want to put a sentence in a label to provide some information. How can I do that? I tried parameters and textview but they didn't work. I tried to put another setcontentView but it can't work either.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
doMySearch() is a cursor that extracts data from database based on a keyword input by user.
public void onPostExecute() {
SimpleCursorAdapter adapter;
Int count = doMysearch().getCount;
If (count >= 1){
adapter=new SimpleCursorAdapter(this, R.layout.activity_results,
doMySearch(), new String[] {
DB.COL_NAME,
DB.COL_CITY },
new int[] { R.id.lblName, R.id.lblCity },
0);
setListAdapter(adapter);
}
Else {
}
I just want a sentence that says "No data found" for the Else part. Thanks.

It is not clear for me what you are asking but here we go.
There is empty view setting in ListView for empty lists, you have to add another empty view in your current layout. Then you will set the empty view layout in code like below:
//add to your layout
<LinearLayout
android:id="#+id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="There is no item" >
</TextView>
</LinearLayout>
//set empty view
ListView listView = (ListView) container.findViewById(R.id.list);
LinearLayout emptyView = (LinearLayout) container.findViewById(R.id.empty);
listView.setEmptyView(emptyView);

As far as I understand the label doesn't show up because of the listview, right?`
EDIT:
Okay I think I get it now.
To keep it simple you could hide your ListView with myList.setVisibility(View.GONE);
Then make a premade Label visible with myLabel.setVisibility(View.VISIBLE) that already holds your error-string.
The harder way you could make a StringArray, like this in (for example) the strings.xml
<string-array name="error">
<item>No results found</item>
</string-array>
Then, in your else-block you can do somethink like that:
ListView lv = (ListView) findViewById(R.id.myList);
String[] content = getResources().getStringArray(R.array.error);
ArrayAdapter<String> typeList = new ArrayAdapter<String>(this, R.layout.simple_list_item_custom, content);
lv.setAdapter(typeList);

Related

confused about Textview and Listview for displaying a list

I tried a few different layouts to get deeper in possibilities and variances.
I started with an array to display the items in an listview that worked fine.
Now I wanted to display items that I got out of a database via JSON.
I get the following error: You must supply a resource ID for a TextView
I used the same XML-file, that worked before, here my all_products.xml:
<?xml version="1.0" encoding="utf-8"?>
<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">
<ListView
android:id="#+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/colorPrimaryDark"
android:dividerHeight="1px">
</ListView>
</LinearLayout>
In my java class I used the code that I used before for the array adapter, I changed only the parameter which should be displayed. Here part of my AllProductsActivity.java:
private void processValue(ArrayList<String> result) {
{
ArrayAdapter adapter = new ArrayAdapter<String>(AllProductsActivity.this, R.layout.all_products, result);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
}
result comes from my asynctask. here a snippet as well:
JSONArray jsonArray = new JSONArray(result.toString())
ArrayList<String> listdata = new ArrayList<String>();
for(int n = 0; n < jsonArray.length(); n++)
{
JSONObject object = jsonArray.getJSONObject(n);
listdata.add(object.optString("nr"));
}
return listdata;
protected void onPostExecute( ArrayList<String> result) {
pdLoading.dismiss();
processValue(result);
}
Why I get the error? And perhaps what about using only a Textview. As I was searching for the toppic, I found different threats where people using Textviews instead of Listview.
EDIT: So it works I added another xml file, mytextview.xml
<TextView android:id="#+id/mytext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/colorPrimaryDark"
android:dividerHeight="1px"
xmlns:android="http://schemas.android.com/apk/res/android">
and changed the adapterstatement to the following:
ArrayAdapter adapter = new ArrayAdapter<String>(AllProductsActivity.this,
R.layout.mytextview,R.id.mytext , result);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
when you use custom layout R.layout.all_products then Adapter don't know about the view to set the data from data list
so simply you need to tell the adapter , the ID of your text view to set data on .
ArrayAdapter adapter = new ArrayAdapter<String>
(AllProductsActivity.this,
R.layout.all_products,R.id.your_text_view_id, result);
// ^^^^^^^^^ pass the text view ID
ArrayAdapter (Context context,
int resource,
int textViewResourceId,
T[] objects)
or
If you just want to display your data without any custom layout then can use in build android resource layout as
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,result);
in Pavneet's first solution take care that:
resource: is the resource containing a textView not your xml file that contain the list itself (not R.layout.all_products)
textViewResourceId: the ID of the textView contained in the resource
When instantiating your ArrayAdapter, the id you provide must be from a layout containing only a TextView. That is what the error You must supply a resource ID for a TextView means

Implement Dynamic textviews inside Asynctask 's onPostExecute method

I am downloading some data from the internet in an Asynctask class.So for that i am using doInBackground function. After this function is executed i am returning the value to onpostexecute method.
In this onpostexecute method
i need to make dynamic textviews.
P.S: I am getting all the data in my for loop, i am not getting any errors, i just cannot form the dynamic textviews.
This is my code:
protected void onPostExecute(String file_url) {
//Links.setText(file_url);
int iterator=0;
Elements linksText = doc.select("#chapters .tips");
for (Element link : linksText) {
link_link = link.attr("href");
narutoLinks[iterator]=link_link;//from latestlinks
System.out.println("narutoLinks[iterator]= "+iterator+" "+link_link);
link_Text = link.text();
narutoLinkHeadingName[iterator]=link_Text;
System.out.println("narutoText[iterator]= "+iterator+" "+narutoLinkHeadingName[iterator]);
iterator++;
}
System.out.println("iterator= "+iterator);
TextView[] textViewArray = new TextView[iterator];
for( int i = 0; i < iterator; i++) {
textViewArray[i] = new TextView(narutoLinksOnly.this);
textViewArray[i].setText(narutoLinkHeadingName[i]);
textViewArray[i].setId(i);
textViewArray[i].setTextColor(0xff000000);
textViewArray[i].setTextSize(20);
textViewArray[i].setOnClickListener(this);
textViewArray[i].setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
((LinearLayout) linearLayout).addView(textViewArray[i]);
}
System.out.println("senkai");
if(connectionTimeout==true)
{showToast("Connection Timeout");
connectionTimeout=false;
}
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
// Displaying downloaded image into image view
// Reading image path from sdcard
}
and this is my xml file
<?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="fill_parent"
android:background="#color/Ivory"
android:id="#+id/dynamicTextview1"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/tvNarutoLinksOnly"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:textColor="#color/black" />
</ScrollView>
</LinearLayout
This is how my oncreate method looks like:
View linearLayout;//declaring it inside the class itself
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.narutolinksonly);
linearLayout = findViewById(R.id.dynamicTextview1);
initialize();
new DownloadLinksFromURL().execute(url);
System.out.println("inside on create");
}
Am i missing something in my code?
Also what is the best way to achieve dynamic textview after getting data from an Asynctask class?
Kindly help.
use a listview instead.
And set an array adapter to it with the list of string that you get from the server.
But in your case try:
textViewArray[i].setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
you have to setup a listview adapter. You have the data, but nothing on your onCreateView ties that data to a listView.
Here's an example from the Android site on an adapter using cursors
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME};
int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1
// Create an empty adapter we will use to display the loaded data.
// We pass null for the cursor, then update it in onLoadFinished()
mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null,
fromColumns, toViews, 0);
setListAdapter(mAdapter);
Trade their cursor data in for your textViewArray data and make it a BaseAdapter or similar and you're done

Updating crossed-out items on loading ListView

I am fairly new to Android programming and trying to set items in a listview upon loading the information from internal storage.
I have two global arrays that I am using: first one is a String array that has the names of the items in the list, and the second is a boolean array that keeps track of which items are crossed out. I am using a TextView in the listview.
main_activity.xml:
<ListView
android:id="#+id/listViewMyList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
rowlayout.xml:
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:text="#+id/label" />
I have created an onClickListener() which successfully updates the state of each list item:
public class MainActivity extends Activity
{
// Initialize the list (global list values)
String[] values = new String[0]; // array of items for the list
boolean[] checkedVals = new boolean[0]; // keep track of which items are crossed-off
String localFileName = "myListData.csv";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// read the data from file if present
readListFromFile();
// find the ListView
ListView lst = (ListView) findViewById(R.id.listViewMyList);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.rowlayout, R.id.label, values);
lst.setAdapter(adapter);
// define what happens on click
lst.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
// read crossed status and set text flags for strikethrough
if (checkedVals[position])
{
TextView text1 = (TextView)view.findViewById(R.id.label);
text1.setPaintFlags(text1.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
text1.setTextColor(0xff000000);
checkedVals[position] = false;
}
else
{
TextView text1 = (TextView)view.findViewById(R.id.label);
text1.setPaintFlags(text1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
text1.setTextColor(0xff888888);
checkedVals[position] = true;
}
// save the data in a file
saveListToFile();
}
});
}
So this code works fine for crossing out and un-crossing out the items. I don't know how can I cross-out some of the items (determined by the checkedVals boolean array) without clicking or any activity when I load the list.
Thanks in advance.
You need to create a custom Adapter by extending ArrayAdapter and overriding getView().
The getView() method loads every row's layout, this is where you should check if the row is in your checkedVals array and draw with the appropriate flags. This Google Talk by an Android lead programmer, Romain Guy, provide a wealth of information about best practices on how to do this.

problems with renaming ListView in xml file

I am playing around with ListView in android and I have a simple class that extends ListActivity.
Whenever I change the name of the ListView in xml file from android:list to something else my program crashes.
Here is my ListActivity code:
private NewExpenseScreenModel mDbAdabter;
String[] items = { "Category", "Month", "Year"};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.statistics);
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter adapter = new ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
mDbAdabter = new NewExpenseScreenModel(this);
populateFields();
}
private void populateFields()
{
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.spending_row, mDbAdabter.getAllCategories());
setListAdapter(adapter);
}
and here is my xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Spinner
android:id="#+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="#string/spinner_title"
/>
<ListView android:id="#+id/android:list" android:layout_height="wrap_content" android:layout_width="match_parent"></ListView>
</LinearLayout>
any idea what is going on..
I want to implement a onItemClickedListener later on so I want to be able to find the ListView by id.
I dont really understand why i cannot just change the id
Additional Info:
I also have another class that uses a different xml file with a list id="android:list" but I never need to find that listView by id so its not a problem.
The other class uses the same xml file to describe layout of each row.
Update:
I managed to access the id by using findViewById(android.R.id.list); instead of findViewById(R.id.list); but i still dont understand why it wont let me rename the list
The list view id should be #android:id/list.
You use + in id when you define a new id. Since you are using ListView id of the listview should have list and list id is already defined internally, so no need to add +.
Edited
The above is mandatory when you extend the class from ListActivity. See #Mejonzhan answer why so.
Now, if you want your own id or when you want to have many List Views, then do not extend ListActivity instead extend Activity and handle the ListViews as below:
Change id as follows:
<ListView android:id="#+id/myListView"
And in the code, access the list view as follows:
ListView myListView = (ListView) findViewById(R.id.myListView)
Try this ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item_1,
items);, in place of `ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item,
items); `
ListActivity has a default layout that consists of a single, full-screen list in the center of the screen. However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain a ListView object with the id "#android:id/list" (or list if it's in code)
ListActivity extend Activity, you can search the source code ,find the ListActivity, and find the function:
public void onContentChanged() {
239 super.onContentChanged();
240 View emptyView = findViewById(com.android.internal.R.id.empty);
241 mList = (ListView)findViewById(com.android.internal.R.id.list);
242 if (mList == null) {
243 throw new RuntimeException(
244 "Your content must have a ListView whose id attribute is " +
245 "'android.R.id.list'");
246 }
247 if (emptyView != null) {
248 mList.setEmptyView(emptyView);
249 }
250 mList.setOnItemClickListener(mOnClickListener);
251 if (mFinishedStart) {
252 setListAdapter(mAdapter);
253 }
254 mHandler.post(mRequestFocus);
255 mFinishedStart = true;
256 }
in line 241 mList = (ListView)findViewById(com.android.internal.R.id.list);
so you can not change the list name

Adding new elements to the top of the ListView

I'm writing an IM client and I need to download (from filesystem or network) and show new elements at the top of ListView (it is history of messages -- older messages are at the top, newer -- at the bottom). I implemented my own Adapter for ListView but I can't add new elements at the beginning of the list and redraw it. (notifyDataSetChanged() isn't good for me, because indexes of messages in ListView changes and android can't redraw it normally).
How do other apps do something similar?
I don't create special code for it, I am simply creating new Adapter for my ListView:
messagesListView.setAdapter(new MessagesListAdapter(this));
And redefine getView() and getCount() method in MessagesListAdapter (extends ArrayAdapter now).
My XML for ListView is
<ListView
android:id="#+id/dialog_messages_list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_marginTop="#dimen/title_height">
</ListView>
And my XML for one element (one message) is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/dialogMessageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:background="#drawable/dialog_message_in"
/>
<TextView
android:id="#+id/dialogMessageDatetime"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""/>
</LinearLayout>
May be you need other code?
EDIT: I tried
messagesListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList));
(new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
arrayList.add(0, "qwer");
}
}).start();
But it also not seems good. I tried to call ((ArrayAdapter<String>)messagesListView.getAdapter()).notifyDataSetChanged(); in thread, but it makes exception.
I suggest reversing the order of the List to display the newest result first.
Run this example:
public class Example extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] array = {"oldest", "older", "old", "new", "newer"};
List<String> list = new ArrayList<String>();
Collections.addAll(list, array);
Collections.reverse(list);
// When you want to add new Strings, put them at the beginning of list
list.add(0, "newest");
ListView listView = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
}
}
You don't have to override anything in the ArrayAdapter or ListView this way.
you can programmatically add some views in the class associated with your list view. For example:
To add stuff to a layout and make new elements:
TextView tv = new TextView(getApplicationContext());
EditText edit = new EditText(getApplicationContext());
relative.addView(tv);
relative.addView(edit);
This is to manipulate an existing element in the xml layout:
final TextView tv = (TextView) v.findViewById(R.id.listItem);
tv.setText("This an item I am changing");
If you look at some of the related questions, they will give your more information on this. But you can also checkout other people's custom listviews and adapters online. This one is really nice: http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

Categories

Resources