This question already has answers here:
Your content must have a ListView whose id attribute is 'android.R.id.list'
(7 answers)
Closed 7 years ago.
I have written code about ListView in Android with Eclipse. I have followed tutorial based on book. But after i copied the code and run with Emulator. The Force Close message appeared. Like the image below:
I don't know whats the probem occured. Instead, i have searched the solution in this question:
Can't create android onListItemClick method
And my code like the image below:
The image below shown the logcat:
Can you give me solutions?
Make sure your ListView is named <ListView android:id="#android:id/list".
Since you are using a ListActivity (the same goes for ListFragments), this is the only possible name for your ListView.
try this,
xml
<?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/output"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#758AA7"
android:padding="1px"
android:text="Click : "
android:textColor="#ffffff" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
MainActivity.java
public class MainActivity extends ListActivity {
TextView content;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_main);
content = (TextView) findViewById(R.id.output);
String[] CoffeeShop = {"Creation","Starbucks","Caribou","Mo'Joe" };
// Define a new Adapter
// First parameter - Context
// Second parameter - Layout for the row
// Third - the Array of data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, CoffeeShop);
// Assign adapter to List
setListAdapter(adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// ListView Clicked item index
int itemPosition = position;
// ListView Clicked item value
String itemValue = (String) l.getItemAtPosition(position);
content.setText("Click : \n Position :" + itemPosition
+ " \n ListItem : " + itemValue);
}
}
Related
This question already has answers here:
AndroidStudio Cannot Find Layout
(2 answers)
Closed 2 years ago.
I am using Android Studio. I am currently trying to make a custom adapter and I have been having trouble with my .xml files. Although I have created them and added the content I would like to see in them, when I call for them in the main activity Java file, I get an error saying it does not exist. Additionally, the SetOnItemClickListener and setAdapter will not work. None of my other files show any sort of errors.
.xml I would like to show, titled characteritem_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">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/detail_name"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/detail_status"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/detail_explanation"/>
</LinearLayout>
My code for the main activity:
package com.example.app.activities;
import ...
public class MainActivity extends AppCompatActivity {
private Button denButton;
private Button sweButton;
private Button aboutButton;
private TextView welcome;
private ArrayList<CharacterItem> characters;
private ListView charList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setContentView(R.layout.characteritem_layout)
welcome = findViewById(R.id.welcome_screen);
//The other buttons work perfectly well.
initializeList();
final CharacterAdapter charAdapter = new CharacterAdapter(this, R.layout.characteritem_layout, characters);
characters.setAdapter(charAdapter);
characters.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), CharacterActivity.class);
intent.putExtra("charItem", characters.get(position));
startActivity(intent);
}
});
private void initializeList(){
characters = new ArrayList<CharacterItem>();
characters.add(new CharacterItem("Finland", false, "Not in progress yet"));
characters.add(new CharacterItem("Norway", true, "Getting the Viking trio in first!"));
characters.add(new CharacterItem("Iceland",false,"He's next!"));
}
}
first of all, to use setContentView twice will not be working in way you want
in my case, right click layout folder and then chose new Layout Resource file works
I have the result of a sql query expressed in this way :
//The column attributes of a result table
ArrayList<String> columns_attributes;
// This contains the data of every row of the result
ArrayList<ArrayList<String>> rows_data;
How can i dinamically display it on an activity ? Thanks
MainActivity
public class MainActivity extends AppCompatActivity {
List<String> list = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list.add("Android");
list.add("iPhone");
list.add("Windows");
list.add("Blackberry");
list.add("Mac");
list.add("Laptop");
list.add("LCD");
list.add("Dell");
ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.list_view_item, list);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "Clicked: " + list.get(position), Toast.LENGTH_SHORT).show();
}
});
listView.setAdapter(adapter);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.vzw.www.listviewalert.MainActivity">
<ListView
android:id="#+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold" >
</TextView>
You can iterate over these list with simple for loops like this:
// for columns
for (String colAttr : columns_attributes) {
// do something with the string value
}
// for rows
for (List<String> row : rows_data) {
for (String rowAttr : row) {
// do something with the string value
}
}
To display a dynamic amount of data, a ListView is recommended to do the job. If you just want to display those strings, you can use a ListActivity and assign a ArrayAdapter to that ListView with the setListAdapter() method.
You may want to check this tutorial to get this done.
http://androidexample.com/Create_Listview_With_ListActivity_-_Android_Example/index.php?view=article_discription&aid=66
How do I create a working ListView in Android?
I am not looking for you to just fix my code, but am looking for a simple working example of a ListView in Android so I can understand the process of creating one and working with it. But I have included my code so you can see where I am coming from and what I have been trying.
I have done the following and had no success:
--
Made a xml layout with only a TextView item in it:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/dir_text_view"
/>
Created the following class as per the instructions at the following tutorial:
http://www.vogella.com/tutorials/AndroidListView/article.html
public class DataTempleArrayAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public DataTempleArrayAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
#Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
#Override
public boolean hasStableIds() {
return true;
}
}
And in the main activity I have a snippet of code where I attempt to add a list of strings to the ArrayList associated with the DataTempleArrayAdapter here:
int i;
for (i=0;i<dirContents.length;i++) {
dirList.add(dirContents[i]);
//Toast.makeText(this, dirList.get(i), Toast.LENGTH_SHORT).show();
}
adapter.notifyDataSetChanged();
dirList is successfully populated, while the adapter doesn't update the ListView at all.
--
Before you ask for it, here I am including the rest of the relevant code:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
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="org.hacktivity.datatemple.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:hint="#string/directory"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="#+id/dirEditText" />
<Button
android:text="→"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="#+id/dirButton"
android:onClick="populateDirList" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:id="#+id/dirListView" />
</LinearLayout>
</RelativeLayout>
And alas the MainActivity class:
public class MainActivity extends AppCompatActivity {
ListView dirListView;
EditText et;
DataTempleArrayAdapter adapter;
ArrayList<String> dirList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dirListView = (ListView) findViewById(R.id.dirListView);
et = (EditText) findViewById(R.id.dirEditText);
dirList = new ArrayList<String>();
dirListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
"Click ListItem Number " + position, Toast.LENGTH_LONG)
.show();
populateDirList(view);
}
});
ArrayList<String> dirList = new ArrayList<String>();
adapter = new DataTempleArrayAdapter(this,
R.id.dir_text_view, dirList);
dirListView.setAdapter(adapter);
}
public void populateDirList (View view) {
File f;
// NO INPUT.
if (et.getText().toString().equals("")) {
Toast.makeText(this, "empty string", Toast.LENGTH_SHORT).show();
return;
}
f = new File(et.getText().toString());
if (f == null) { return; }
String dirContents[] = f.list();
if (dirContents == null) { return; }
dirList = new ArrayList<String>(Arrays.asList(f.list()));
adapter.clear();
int i;
for (i=0;i<dirContents.length;i++) {
dirList.add(dirContents[i]);
//Toast.makeText(this, dirList.get(i), Toast.LENGTH_SHORT).show();
}
adapter.notifyDataSetChanged();
}
}
One of the best resources for understanding ListView is indeed the
one you mentioned from Vogella
Another cool resource to understand how the the
notifyDataSetChanged() method works in ListView this post from StackOverflow
For a short, simple explanation of how to use CustomLayouts in
ListView (without the ViewHolder pattern) check another of the best
references available: Mkyong
Discussing the benefits of the ViewHolder pattern in ListView:
check this StackOverflow post
Concise example and explanation of the ViewHolder pattern in
ListView: check this example from JavaCodeGeeks
And to fix your code I think the answer given before is only part of the problem:
You must indeed comment the line
//ArrayList<String> dirList = new ArrayList<String>();
because, like #F43nd1r mentioned this would also be a different instance of a list passed into the adapter
but there is more, when you do this:
dirList = new ArrayList<String>(Arrays.asList(f.list()));
you are instantiating a new, different, list, the old reference held by the adapter will NOT be changed... it will still hold the OLD object list
you should perhaps substitute it for something like:
dirList.clear();
dirList.addAll(Arrays.asList(f.list()));
Hope this helps!
Excerpt from your code:
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
dirList = new ArrayList<String>();
//...
ArrayList<String> dirList = new ArrayList<String>();
adapter = new DataTempleArrayAdapter(this,
R.id.dir_text_view, dirList);
//...
}
I bet you already see what the problem is, but in case you don't: You have a field and a local variable with the same name. You pass the local variable to the adapter. It is only naturally that the adapter does not react to changes on the field, as it has no knowledge of its existence.
I think what you have done wrong is to supply a UI Component to the Array Adapter with:
adapter = new DataTempleArrayAdapter(this, R.id.dir_text_view, dirList);
The second item should not be an ID, but a layout file. Android have already implemented a List item layout with a textview that you can use: android.R.layout.simple_list_item_1.
so replace your row with
adapter = new DataTempleArrayAdapter(this, android.R.layout.simple_list_item_1, dirList);
and you are one step closer.
(This way you don't need your "xml layout with only a TextView item in it")
This question already has an answer here:
Android System services not available to Activities before onCreate() [closed]
(1 answer)
Closed 10 years ago.
How could I add items from listView(on my layout) from array?
I tried multiple times, but everytime I get error: System services not avaliable before onCreate.();. Yes, I. know that this er.ror is shown when I try to access ArrayAdapter. Tried almost everything. .Full code is here: pastebin.com/Nv5BkcS7
UPDATE
I followed some other tutorials. My code works now, but there is no data. http://pastebin.com/D8UFKC7i and xml http://pastebin.com/mJfwjGcB
Could someone tell me why it doesn't work.? Debugger says that arrays have all entires
Your onCreate() method is blank in the addcontacts activity, thats the problem:
public class addcontacts extends ListActivity {
protected void onCreate() {
//set content here
setContentView(R.layout.activity_add_contact);
}
...
...
And Don't forget to create activity_add_contact.xml in Layout folder
with content :
<?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" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
1.create a custom Adapter exteding BaseAdpter or ArrayAdpter and pass array or ArrayList in constructor.
2.Create the View in layout (of row )
3.inflate this xml in getview function of custom Adapter and set the data.
Activity 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="wrap_content"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/lstText"
/>
</LinearLayout>
list row XML (in layout row.xml)
<?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">
<LinearLayout
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:id="#+id/txtAlertText" />
</LinearLayout>
</LinearLayout>
Create Adapter Class inside your activity
class JSONAdapter extends BaseAdapter implements ListAdapter {
private final Activity activity;
private final JSONArray jsonArray;
private JSONAdapter (Activity activity, JSONArray jsonArray) {
assert activity != null;
assert jsonArray != null;
this.jsonArray = jsonArray;
this.activity = activity;
}
#Override public int getCount() {
if(null==jsonArray)
return 0;
else
return jsonArray.length();
}
#Override public JSONObject getItem(int position) {
if(null==jsonArray) return null;
else
return jsonArray.optJSONObject(position);
}
#Override public long getItemId(int position) {
JSONObject jsonObject = getItem(position);
return jsonObject.optLong("id");
}
#Override public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = activity.getLayoutInflater().inflate(R.layout.row, null);
TextView text =(TextView)convertView.findViewById(R.id.txtAlertText);
JSONObject json_data = getItem(position);
if(null!=json_data ){
String jj=json_data.getString("f_name");
text.setText(jj);
}
return convertView;
}
}
Then add this in your activity.
public class main extends Activity {
/** Called when the activity is first created. */
ListView lstTest;
//Array Adapter that will hold our ArrayList and display the items on the ListView
JSONAdapter jSONAdapter ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Initialize ListView
lstTest= (ListView)findViewById(R.id.lstText);
jSONAdapter = new JSONAdapter (main.this,jArray);//jArray is your json array
//Set the above adapter as the adapter of choice for our list
lstTest.setAdapter(jSONAdapter );
}
And you are done.
I am populating a Listview (list.xml) with a textview (list_row.xml).
I need to add an additional textview to list_row.xml, which means I need to wrap them in a layout. However, I get a Textview ID error when I do this.
list_row.xml I need:
<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:id="#+id/nameTV"
android:textSize="14sp"
android:textStyle="bold"
android:textColor="#FFFF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Main.xml
public View GetView(int inPosition, View inConvertView, ViewGroup inParent)
{
View _row = inConvertView;
if (_row == null)
{
// Inflate Row
Log.d(TAG, "Starting XML Row Inflation ... ");
LayoutInflater inflater = (LayoutInflater)
cContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
_row = inflater.inflate(R.layout.list_row, inParent, false);
Log.d(TAG, "Successfully completed XML Row Inflation!");
}
// Get item
PropertiesAd _adProperty = GetItem(inPosition);
// Get reference to TextView - country_name
cAdName = (TextView) _row.findViewById(R.id.nameTV);
//Set name
cAdName.setText(_adProperty.toString());
return _row;
}
For the sake of testing, I haven't added the second textview yet. I'm just trying to get this to work with the layout wrapper.
Everything works fine without the LinearLayout. But again, I will need it to add a second textview. Suggestions?
Thanks
ArrayAdapter:
public class ArrayAdapterAd extends ArrayAdapter<PropertiesAd>
{
private static final String TAG = "AdArrayAdapter";
private Context cContext;
private TextView cAdName;
private List<PropertiesAd> cAdList = new ArrayList<PropertiesAd>();
public ArrayAdapterAd(Context inContext, int inTextViewResourceId, List<PropertiesAd> inObjects)
{
super(inContext, inTextViewResourceId, inObjects);
this.cContext = inContext;
this.cAdList = inObjects;
}
public int GetCount()
{
return this.cAdList.size();
}
public PropertiesAd GetItem(int inIndex)
{
return this.cAdList.get(inIndex);
}
public View GetView(int inPosition, View inConvertView, ViewGroup inParent)
{
View _row = inConvertView;
if (_row == null)
{
// Inflate Row
Log.d(TAG, "Starting XML Row Inflation ... ");
LayoutInflater inflater = (LayoutInflater)
cContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
_row = inflater.inflate(R.layout.ad_list, inParent, false);
Log.d(TAG, "Successfully completed XML Row Inflation!");
}
// Get item
PropertiesAd _adProperty = GetItem(inPosition);
// Get reference to TextView - country_name
cAdName = (TextView) _row.findViewById(R.id.ad_listTextView);
//Set country name
cAdName.setText(_adProperty.toString());
return _row;
}
}
Now I see your problem... you cannot do that extending the ArrayAdapter class. Instead, extend BaseAdapter.
Here is xml for a listview "list_row" with 2 textviews
<?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="horizontal">
<TextView android:id="#+id/text1" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:id="#+id/text2" android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
I'm assuming the getView() is from an ArrayAdapter subclass? If so, what does your constructor look like? Perhaps you're passing in an id reference in stead of a layout reference? This will probably resolve fine if you're whole layout is nothing more than a single TextView, but could explain why an error occurs when wrapping it in a layout.
Also, don't forget to implement the rowwrapper/viewholder pattern to improve performance and recycle views. For an example, have a look here.
By the way, you may even suffice with one of the Android built-in layouts. There a two line list item layout defined in android.R.layout.simple_list_item_2. It may not suit your needs though, as the styling on the two elements is different. A custom layout is always the most flexible in the end. :)