-1

I get how to do this for a simple ListView, something like:

listView.setOnItemClickListener(new OnItemClickListener() {

              @Override
              public void onItemClick(AdapterView<?> parent, View view,
                 int position, long id) {

But whenever I do it in my activity I get a nullpointerexception.

Could someone please show me how it is supposed to be? Thanks!

EDIT: I'm sorry! Didn't want to fill up an entire question only with code, I think it's necessary in this case, so I'm putting my entire java code below:

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;


public class Save extends ListActivity {
String FileName;
EditText et;
String listItem[]={};
ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_save);
    Button save = (Button) findViewById(R.id.SAVE); //this is my button
    final EditText title = (EditText) findViewById(R.id.save_filename); //This is unused
    final EditText maintext = (EditText) findViewById(R.id.test);
    getActionBar().setDisplayUseLogoEnabled(false);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    et = (EditText) findViewById(R.id.save_filename);
    listView = (ListView) findViewById(R.id.list); //I've specified this listView only for the OnItemClickListener action

    List values = new ArrayList();
    for (int i = 0; i < listItem.length; i++) {
        values.add(listItem[i]);
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, values);
    setListAdapter(adapter);

    save.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            try {
                FileName = et.getText().toString() + ".txt";
                FileOutputStream fout = openFileOutput(FileName, Context.MODE_PRIVATE);
                OutputStreamWriter outsw = new OutputStreamWriter(fout);
                try {
                    outsw.write(String.valueOf(maintext));
                    outsw.flush();
                    outsw.close();
                    Toast.makeText(getBaseContext(), "Your file has been saved", Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter();
            String device;
            switch (view.getId()) {
                case R.id.SAVE:
                    List myList = new ArrayList();
                    device = et.getText().toString();
                    myList.add(device);
                    adapter.add(device);
                    et.setText("");
                    break;
            }
            adapter.notifyDataSetChanged();
        }
    });

    //I think this is wrong, I get no error in Java by the way. How could this work if there's a specific extension for my activity that define the listview? **That's my question**. 
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            // ListView Clicked item index
            int itemPosition     = position;

            // ListView Clicked item value
            String  itemValue    = (String) listView.getItemAtPosition(position);

            // Show Alert
            Toast.makeText(getApplicationContext(),
                    "Position :"+itemPosition+"  ListItem : " +itemValue , Toast.LENGTH_LONG)
                    .show();
        }
    });

}

And the xml:

<Button
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:id="@+id/SAVE"
    android:text="@string/save_button" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/save_filename"
    android:layout_alignRight="@+id/linearLayout"
    android:hint="@string/save_hint"
    android:layout_alignEnd="@+id/linearLayout"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="5dp" />

<ListView
    android:id="@android:id/list"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_above="@+id/linearLayout"
    android:layout_below="@+id/save_filename">
</ListView>

Sorry again for the cunfusion!!

Lampione
  • 1,622
  • 3
  • 21
  • 39

1 Answers1

0

The problem here comes from the fact that you are using ListActivity instead of Activity. For this reason the ListView's ID is not added to the R file so it is not callable by the findById call. This would not happen if Activity were used. When using ListActivity you can use the built in getListView() method to get the ListView object. Also when I ran your given code I got an error that a listView had to be defined by the ID list. This comes from an error in your XML file when you defined the ID.

Below I posted two sections from your given XML

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/save_filename"

<ListView
    android:id="@android:id/list"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_above="@+id/linearLayout"
    android:layout_below="@+id/save_filename">
</ListView>

Notice when defining the id, the top one says android:id="@+id/save_filename" while the bottom says android:id="@android:id/list". Also when you use save_file_name it is done like thisandroid:layout_below="@+id/save_filename"This is incorrect. To define an id you use@+id`. This should be done the first time an element is referenced. It tells android to generate a value for it in R.java. Errors like this in your XML can cause your R.java file to not be generated and lead to different problems but I think the extra pluses on the ids are forgivable.

I was getting the error because of how you defined the id for layout. Instead it should look more like this

android:id="@+id/android:list"

Notice the + to create a new id and because I am using ListActivity I also must define it as android:list instead of just list. I changed your XML to this:

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/save_filename"
    android:layout_alignRight="@+id/linearLayout"
    android:hint="save here"
    android:layout_alignEnd="@id/linearLayout"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="5dp" />

<ListView
    android:id="@+id/android:list"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_above="@id/linearLayout"
    android:layout_below="@id/save_filename">
</ListView>

Here is some corrected code, I noted what I changed.

package com.example.sosandbox;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;


public class Save extends ListActivity {
String FileName;
EditText et;
//Added some test values
String listItem[]={"1","2","3","4","5"};
ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_save);
    Button save = (Button) findViewById(R.id.SAVE); //this is my button
//    This is unused so I commented it out
//    final EditText title = (EditText) findViewById(R.id.save_filename); //This is unused
    final EditText maintext = (EditText) findViewById(R.id.save_filename);
    getActionBar().setDisplayUseLogoEnabled(false);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    et = (EditText) findViewById(R.id.save_filename);
//    This is your issue. 
//    listView = (ListView) findViewById(R.id.list);
//    Change it to this because you are using a listActivity
    listView = getListView();//I've specified this listView only for the OnItemClickListener action

    List values = new ArrayList();
//    This won't run because you initilize listItem to an empty array or 0 so 0 < 0 evaluates to false and the loop doesn't run
    for (int i = 0; i < listItem.length; i++) {
        values.add(listItem[i]);
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, values);
    setListAdapter(adapter);

    save.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            try {
                FileName = et.getText().toString() + ".txt";
                FileOutputStream fout = openFileOutput(FileName, Context.MODE_PRIVATE);
                OutputStreamWriter outsw = new OutputStreamWriter(fout);
                try {
                    outsw.write(String.valueOf(maintext));
                    outsw.flush();
                    outsw.close();
                    Toast.makeText(getBaseContext(), "Your file has been saved", Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter();
            String device;
            switch (view.getId()) {
                case R.id.SAVE:
                    List myList = new ArrayList();
                    device = et.getText().toString();
                    myList.add(device);
                    adapter.add(device);
                    et.setText("");
                    break;
            }
            adapter.notifyDataSetChanged();
        }
    });

    //I think this is wrong, I get no error in Java by the way. How could this work if there's a specific extension for my activity that define the listview? **That's my question**. 
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            // ListView Clicked item index
            int itemPosition     = position;

            // ListView Clicked item value
            String  itemValue    = (String) listView.getItemAtPosition(position);

            // Show Alert
            Toast.makeText(getApplicationContext(),
                    "Position :"+itemPosition+"  ListItem : " +itemValue , Toast.LENGTH_LONG)
                    .show();
        }
    });

}
}
user3282276
  • 3,674
  • 8
  • 32
  • 48
  • 1
    Thank you for your complete answer! Notice that Android Studio itself suggested me to define the ID in that way so Android:id="@android:id/list", It's strange anyway because the entire code worked for me until I've defined my listview by id. So I've only changed this line: listView = getListView(); And all worked! Basically it was a single line giving the error, thank you!! – Lampione May 31 '14 at 06:59