I want to create a BaseAdapter for a ListView. From my database I get an ArrayList that contains the entries for the ListView. The onCreate Method works fine but if I click the button to insert data to the database and display it in the ListView my app crashes. I'm looking for the Solution but can't find it. Maybe you do.
Logcat says there is a NullPointerException at the point where the text of the TextView is set (LaunchActivity$CustomAdapter.getView).
LaunchActivity.java
public class LaunchActivity extends Activity {
ImageView buttonAdd;
EditText insertText;
SubjectAdapter helper;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch);
helper=new SubjectAdapter(this);
listView = (ListView) findViewById(R.id.listViewLaunch);
listView.setEmptyView(findViewById(R.id.emptyView));
insertText = (EditText) findViewById(R.id.editTextLaunch);
buttonAdd = (ImageView) findViewById(R.id.imageViewLaunch);
buttonAdd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String subject = insertText.getText().toString();
long id=helper.insertData(subject);
if(id<0){
Log.d("Personal", "insertData not successfull");
} else {
// Hiding the keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(insertText.getWindowToken(), 0);
// loading ListView with newly added data
loadListViewData();
Log.d("Personal", "insertData successfull");
Toast.makeText(LaunchActivity.this, subject+" hinzugefĆ¼gt", Toast.LENGTH_LONG).show();
insertText.setText("");
}
}
});
loadListViewData();
}
public void loadListViewData() {
// database handler
SubjectAdapter helper = new SubjectAdapter(getApplicationContext());
// Get Data from Database and set ArrayList
ArrayList<String> list = (ArrayList<String>) helper.getData();
// Creating adapter for ListView
CustomAdapter adapter = new CustomAdapter(getApplicationContext(), list);
// attaching data adapter to ListView
listView.setAdapter(adapter);
}
class CustomAdapter extends BaseAdapter{
ArrayList<String> list = new ArrayList<String>();
Context context;
// Constructor
CustomAdapter(Context context, ArrayList<String> list){
this.list = list;
this.context = context;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
// LayoutInflation and Recycling
if(row == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.item_listview, parent, false);
}
TextView myText = (TextView) findViewById(R.id.textList);
// Get String from ArrayList
String temp = list.get(position);
// Set Text for TextView inside ListView
myText.setText(temp);
return row;
}
}
}
If row is null you have to inflate and assign the result to row!
row = inflater.inflate(R.layout.item_listview, parent, false);
Also you'll want to get myText from row:
TextView myText = (TextView) row.findViewById(R.id.textList);
First create object of ArrayList<String> in getData() and check code below:
public void loadListViewData() {
// database handler
SubjectAdapter helper = new SubjectAdapter(getApplicationContext());
// Get Data from Database and set ArrayList
ArrayList<String> list = helper.getData();
// Creating adapter for ListView
CustomAdapter adapter = new CustomAdapter(getApplicationContext(), list);
// attaching data adapter to ListView
listView.setAdapter(adapter);
}
class CustomAdapter extends BaseAdapter{
ArrayList<String> list = null;
Context context;
// Constructor
CustomAdapter(Context context, ArrayList<String> list){
this.list = list;
this.context = context;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
// LayoutInflation and Recycling
if(row == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.item_listview, parent, false);
}
TextView myText = (TextView) findViewById(R.id.textList);
// Get String from ArrayList
String temp = list.get(position);
// Set Text for TextView inside ListView
myText.setText(temp);
return row;
}
}
and make sure return type of getData() will be ArrayList<String>
hope it will help.
Related
I have a database with a column named "noteName". What I want is to populate the listView with mySQLiteDatabase. I use a display adapter to help the process.
But the problems come with Null Pointer Exception. I have to try to figure it out what cause the NPO but I still didn't get it.
Please help me, I have just been stuck here for two days.
NB. This my code for MainActivity.java (where the listview will show)
public class MainActivity extends ActionBarActivity {
SQLiteDatabase db;
DatabaseHelper dBHelper = new DatabaseHelper(this);
private ListView list;
private ArrayList<String> NoteName = new ArrayList<String>();
private static final String TABLE_NOTES_NAME = "Notes";
private ArrayList<Contact> noteData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.pink_icon).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent registerIntent = new Intent(MainActivity.this, AddNote.class);
MainActivity.this.startActivity(registerIntent);
}
});
display();
}
public void display() {
db = dBHelper.getReadableDatabase();
Cursor mCursor = db.rawQuery("SELECT NoteName FROM " + TABLE_NOTES_NAME , null);
ListView list = (ListView)findViewById(android.R.id.list);
NoteName.clear();
if (mCursor.moveToFirst()) {
do {
NoteName.add(mCursor.getString(mCursor.getColumnIndex(dBHelper.TOL_NOTENAME)));
} while (mCursor.moveToNext());
}
DisplayAdapterTrans disadptr = new DisplayAdapterTrans(MainActivity.this, NoteName);
list.setAdapter(disadptr); // Here the console says have a null pointer exception
mCursor.close();
}
}
This one for my DisplayAdapter
public class DisplayAdapterTrans extends BaseAdapter {
private Context mContext;
private ArrayList<String> NoteName;
public DisplayAdapterTrans(Context c, ArrayList<String> noteName) {
this.mContext = c;
this.NoteName = noteName;
}
public int getCount() {
// TODO Auto-generated method stub
return NoteName.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.notename, null);
mHolder = new Holder();
mHolder.noteName= (TextView) child.findViewById(R.id.notenameTxt);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.noteName.setText(NoteName.get(pos));
return child;
}
public class Holder {
TextView noteName;
}
}
I've had trouble finding much documentation on using LinkedHashMap with a ListView for Android, but I was able to get the list to populate correctly with the below.
Unfortunately, when I scroll, the list is scrambled the same as it would be if I was using a regular HashMap. I'm not sure what I'm doing wrong.
MainActivity.java (only a portion):
public class MainActivity extends ListActivity {
private ListView dataList;
ArrayList<String> listItems=new ArrayList<String>();
ListViewAdapter adapter;
private ArrayList<LinkedHashMap<String, String>> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataList = (ListView)findViewById(android.R.id.list);
list=new ArrayList<LinkedHashMap<String,String>>();
adapter=new ListViewAdapter(this, list);
dataList.setAdapter(adapter);
addItems();
}
public void addItems() {
LinkedHashMap<String,String> row = new LinkedHashMap<String, String>();
row.put(KEY_COLUMN, key);
row.put(FIRST_COLUMN, dateTime);
row.put(SECOND_COLUMN, data1);
row.put(THIRD_COLUMN, data2);
row.put(FOURTH_COLUMN, data3);
list.add(row);
adapter.notifyDataSetChanged();
}
}
ListViewAdapter Class
public class ListViewAdapter extends BaseAdapter{
public ArrayList<LinkedHashMap<String, String>> list;
Activity activity;
TextView txtKey;
TextView txtFirst;
TextView txtSecond;
TextView txtThird;
TextView txtFourth;
public ListViewAdapter(Activity activity,ArrayList<LinkedHashMap<String, String>> list){
super();
this.activity = activity;
this.list = list;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){
LayoutInflater inflater = activity.getLayoutInflater();
convertView = inflater.inflate(R.layout.list_row_columns, null);
txtKey = (TextView) convertView.findViewById(R.id.row_key);
txtFirst = (TextView) convertView.findViewById(R.id.date_time);
txtSecond = (TextView) convertView.findViewById(R.id.data1);
txtThird = (TextView) convertView.findViewById(R.id.data2);
txtFourth = (TextView) convertView.findViewById(R.id.data3);
}
LinkedHashMap<String, String> map = list.get(position);
txtKey.setText(map.get(KEY_COLUMN));
txtFirst.setText(map.get(FIRST_COLUMN));
txtSecond.setText(map.get(SECOND_COLUMN));
txtThird.setText(map.get(THIRD_COLUMN));
txtFourth.setText(map.get(FOURTH_COLUMN));
return convertView;
}
}
The simplest solution would be to use ArrayAdapter rather than rolling your own BaseAdapter subclass. But, assuming that you really want to extend BaseAdapter...
First, get rid of all of the widgets from the class declaration (e.g., TextView txtKey), moving them to be local variables inside of getView().
Then, populate those local variables whether or not you are inflating a new layout.
Other improvements:
Never use LayoutInflater.from() when you have an Activity. Call getLayoutInflater() on the Activity, so you get a LayoutInflater that knows about your themes and styles.
Use getItem(), instead of list.get(position), in getView(), so getView() and getItem() stay in sync.
I'm trying to make an audio file preview page which consists of a listview of files in a folder. Each row has a play button next to it which changes to a stop button when clicked. I now need a way of setting all the other images to the play button if a row is clicked as only one audio file should be playing at once. I tried iterating through the list and getting the imageview from this but had no luck (shown below):
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
IncidentLogger logger = new IncidentLogger(this.getActivity());
final List<Audio> audioList = logger.getAllAudio();
AudioListViewAdapter adapter = new AudioListViewAdapter(audioList, getActivity());
final ListView listView = (ListView) getActivity().findViewById(R.id.listView);
listView.setAdapter(adapter);
OnItemClickListener onItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for(int i = 0; i < audioList.size(); i++) {
View v = listView.getAdapter().getView(i, view, parent);
ImageView imageView = (ImageView) v.findViewById(R.id.control);
imageView.setImageResource(R.drawable.ic_action_play);
}
ImageView iv = (ImageView) view.findViewById(R.id.control);
if(iv.getTag() == "1") {
iv.setTag("0");
iv.setImageResource(R.drawable.ic_action_play);
} else {
iv.setTag("1");
iv.setImageResource(R.drawable.ic_action_stop);
}
}
};
listView.setOnItemClickListener(onItemClickListener);
}
This can be done so easily, you need to just look at on the position of list item that was clicked by user. A well described complete demo code is as below ...
public class ChangeImageInListDynamically extends Activity {
/**
* Adapter for your data.
*/
ImageAdapter adpAR;
ArrayList<String> itemList;
ListView mListView;
ImageAdapter mAdapter;
/**
* Indicate which item is currently selected.
* Its default selected item is '0' e.g., 1st item.
*/
private int selectedPosition=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
itemList = new ArrayList<String>();
for (int i = 0; i < 11; i++) {
itemList.add("Item - "+i);
}
mListView = (ListView)findViewById(R.id.data_list);
//Initialize your adapter
mAdapter = new ImageAdapter(nChangeImageInListDynamically.this, itemList);
//set adapter to your list.
mListView.setAdapter(mAdapter);
//set list click listener.
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> av, View view, int position, long id) {
//your image that need to change dynamically.
ImageView imageView = (ImageView) view.findViewById(R.id.select);
//position of clicked item.
selectedPosition=position;
//change image of respective image.
imageView.setImageResource(R.drawable.selected);
//notify your adapter to update your list.
adpAR.notifyDataSetChanged();
}
});
}
static class ViewHolder {
TextView title;
ImageView img;
}
/**
* Your ImageAdapter.
*/
public class ImageAdapter extends BaseAdapter {
ArrayList<String> dataList;
Context context;
public ImageAdapter(Context context, ArrayList<String> arrayList) {
this.context = context;
this.dataList = arrayList;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return dataList.size();;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
final ViewHolder holder;
Log.d("posiiton ImageAdapater : ",""+position);
if (row == null) {
LayoutInflater inflater = ChangeImageInListDynamically.this.getLayoutInflater();
row = inflater.inflate(R.layout.listrow, null);
holder = new ViewHolder();
holder.title = (TextView) row.findViewById(R.id.text);
holder.img = (ImageView) row.findViewById(R.id.select);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
//set titel text.
holder.title.setText(dataList.get(position));
//Change Image of selected item dynamically.
if(selectedPosition == position) {
//Item is selected.
holder.img.setImageResource(R.drawable.selected);
}else{
//Other non-selected items.
holder.img.setImageResource(R.drawable.dis_selected);
}
return row;
}
}
}
Hello at all the community,
i've a listview with a custom adapter that consists by one textview and one edit text. i set the text for the edit text into the adapter but in my acivity (listview) i want to set the onClickListener at this edit text. ive this code for my getView method
#Override
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
holder = new Holder();
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.my_adapter, null);
holder.textView = (TextView)view.findViewById(R.id.textView);
holder.editText = (EditText)view.findViewById(R.id.editText);
view.setTag(holder);
} else {
holder = (Holder)view.getTag();
}
holder.editText.setText("My text");
holder.textView.setText("text");
return view;
}
#Override
public boolean isEnabled(int position) {
return false;
}
i disablet the click on listview with the isEnabled method because I will not be able to click on the list. in my activity i've only the listview so if i want to set onclicklistener on the edit text of the adapter how can i do this?
public MyAdapterClass(Context context, int textViewResourceId, ArrayList<String> list) {
super(context, textViewResourceId, list);
// TODO Auto-generated constructor stub
this.list = list;
this.context = context;
}
Simply use this
holder.editText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something
}
});
#Override
public boolean isEnabled(int position) {
return true;
}
Please do something like :
private OnClickListener cl;
public MyAdapterClass(Context context, int textViewResourceId, ArrayList<String> list, OnClickListener cl) {
super(context, textViewResourceId, list);
// TODO Auto-generated constructor stub
this.list = list;
this.context = context;
this.cl = cl;
}
then in on getView()set it to EditText :
holder.editText.setOnClickListener(cl);
finally set set an put OnClickListener() like :
OnClickListener cl = new OnClickListener() {
#Override
public void onClick(View v) {
// Logic of Click goes Here.
}
};
where you are setting Adapter to
ListView, like :
adapter = MyAdapterClass(Activity.this, android.R.layout.simple_list_item_1, list, cl);
listView.setAdapter(adapter);
i have implemented a custom array adapter for my project,so far i am able to add and delete items from it and it displays them in the ListView too
dynamically..however i have a button in the MainActivity(that holds the ListView), that when clicked i want to display all the row items.
so far what i am getting instead of the data in the adapter after appending all values to a StringBuilder is:
com.baseadapter.C#4052b9b8com.baseadapter.C#4052f490com.baseadapter.C#40531378com.baseadapter.C#4053415
the arrayadapter and arraylist are set as below:
ArrayList<C> arrayvalues= new ArrayList<C>();
MyAdapter adapter;
adapter= new MyAdapter(MainActivity.this, R.layout.list_item,
arrayvalues);
the code for my collection class is this:
public class C {
String the_text;
public String getText() {
return the_text;
}
public void setText(String the_text) {
this.the_text = the_text;
}
public C(String the_text) {
super();
this.the_text = the_text;
}
}
the code i use to iterate over the adapter is this:
btn_done.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
StringBuilder b = new StringBuilder();
for(int i=0 ; i<adapter.getCount() ; i++){
b.append(adapter.getItem(i));
}
Toast.makeText(getApplicationContext(), b.toString(), Toast.LENGTH_SHORT).show();
}
});
and the custom adapter code(just in case,though i don,t think the problem lies here):
public class MyAdapter extends ArrayAdapter<C> {
Context context;
int layoutResourceId;
ArrayList<C> data = new ArrayList<C>();
public MyAdapter(Context context, int layoutResourceId,
ArrayList<C> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
myholder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new myholder();
holder.tv = (TextView) row.findViewById(R.id.tv_num);
holder.btnDelete = (ImageButton) row.findViewById(R.id.btn_delete);
row.setTag(holder);
} else {
holder = (myholder) row.getTag();
}
C c=data.get(position);
holder.tv.setText(c.getText());
//String c=data.get(position);
//holder.tv.setText(c.g.getName());
holder.btnDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
data.remove(position);
notifyDataSetChanged();
}
});
return row;
}
static class myholder {
TextView tv;
ImageButton btnDelete;
}
}
what should i do to get the actual values in the adapter?ps:kindly attach code,thanks
Change your below loop code. it shall work now.
for(int i=0 ; i<adapter.getCount() ; i++)
{
C itemObject=adapter.getItem(i);
if(itelObject!=null)
b.append(itemObject.getText());
}
You should override the getItem() method in the Adapter:
#Override
public C getItem(int position) {
return data.get(position);
}
And update your loop code to get the text for "C" or override "C" toString() method as was suggested.