ListView with Buttons and String Static Array

I want to create a ListView where each row will have two buttons. Button1 and Button2 .

I read a few tutorials on how to create a CustomAdapter or extend the BaseAdapter , but none of them worked in my case, so I am opening a new question here.

I have a static (non-changing) String Array in my strings.xml :

  <string-array name="locations_array"> <item>Item1</item> <item>Item2</item> </string-array> 

I want to use this array in my ListView (I manage to create a regular ListView with an onClick event, but now I want to add buttons to each row) and add two buttons to each row, each of which will have its own onClick event.

I followed the steps from here answers and several other guides on the Internet, but I always get a NullPointerException when trying to setText .

CustomAdapter.java

 public class CustomAdapter extends BaseAdapter implements ListAdapter { private ArrayList<String> list = new ArrayList<>(); private Context ctx; public CustomAdapter(ArrayList<String> list, Context ctx){ this.list = list; this.ctx = ctx; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { Log.d("TAG", list.get(position)); return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null){ LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.layout_listview,null); } Log.d("TAG", list.get(position)); TextView listItemText = (TextView) view.findViewById(R.id.list_item_string); listItemText.setText(list.get(position)); Button localData = (Button) view.findViewById(R.id.button1); Button onlineData = (Button) view.findViewById(R.id.button2); localData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); onlineData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); return view; } } 

And here I use the adapter in my fragment:

 locationsArray = getResources().getStringArray(R.array.locations_array); ArrayList<String> data = new ArrayList<>(Arrays.asList(locationsArray)); CustomAdapter adapter = new CustomAdapter(data,getActivity()); listView.setAdapter(adapter); 

But that does not work. All tutorials focus on something else than what I need. I just need to just put two buttons on each line with an existing String Array. I do not want to add anything dynamically, etc. Just use this array of strings that I already created.

EDIT (adding XML files that I forgot!)

R.layout.layout_listview (EditText is for filtering the list):

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/et_filter" android:layout_height="wrap_content" android:layout_width="match_parent" android:hint="Search Location"> </EditText> <ListView android:id="@+id/list" android:layout_height="wrap_content" android:layout_width="match_parent"> </ListView> </LinearLayout> 

R.layout.layout_listview_buttons:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/list_item_string" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:paddingLeft="8dp" android:textSize="18sp" android:textStyle="bold" /> <Button android:id="@+id/button1" android:layout_width="80dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:focusable="false" android:focusableInTouchMode="false" android:text="Online Data" android:textColor="#0099CC" /> <Button android:id="@+id/button2" android:layout_width="80dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_below="@+id/button1" android:layout_marginTop="3dp" android:focusable="false" android:focusableInTouchMode="false" android:text="Local Data" android:textColor="#0099CC" /> </RelativeLayout> 

LogCat exception:

 12-15 11:24:10.852 14626-14626/com.inodroid.myweatherapp E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.inodroid.myweatherapp, PID: 14626 java.lang.NullPointerException at com.inodroid.myweatherapp.Data.CustomAdapter.getView(CustomAdapter.java:59) 

Line Code:

 listItemText.setText(list.get(position)); 

Hope someone can help me here.

Greetings

+6
source share
4 answers

Try the following:

main.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" > <ListView android:id="@+id/lvItems" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </LinearLayout> 

MainActivity.java:

 public class MainActivity extends Activity { private ListView lvItems; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lvItems = (ListView) findViewById(R.id.lvItems); String[] locationsArray = getResources().getStringArray( R.array.locations_array); CustomAdapter adapter = new CustomAdapter(this, locationsArray); lvItems.setAdapter(adapter); lvItems.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ViewHolder holder = (ViewHolder) view.getTag(); String item = holder.getItem(); // Do what ever with your Item. // If You need the position, you can take it from above // position. } }); } } 

list_item.xml:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="5dp" > <Button android:id="@+id/btnLocalData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="local Data" /> <TextView android:id="@+id/tvItem" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@+id/btnLocalData" android:layout_alignTop="@+id/btnOnlineData" android:layout_toLeftOf="@+id/btnOnlineData" android:layout_toRightOf="@+id/btnLocalData" android:gravity="center" android:text="Item" android:textSize="16dp" android:textStyle="bold" /> <Button android:id="@+id/btnOnlineData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="Online Data" /> </RelativeLayout> 

CustomAdapter.java:

 public class CustomAdapter extends ArrayAdapter<String> { private LayoutInflater lf; public CustomAdapter(Context context, String[] objects) { super(context, 0, objects); lf = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = lf.inflate(R.layout.list_item, parent, false); holder = new ViewHolder(); holder.btnLocalData = (Button) convertView .findViewById(R.id.btnLocalData); holder.btnOnlineData = (Button) convertView .findViewById(R.id.btnOnlineData); holder.tvItem = (TextView) convertView.findViewById(R.id.tvItem); holder.initListeners(); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.setData(getItem(position)); return convertView; } public static class ViewHolder { TextView tvItem; Button btnOnlineData; Button btnLocalData; String mItem; public String getItem(){ return mItem; } public void setData(String item) { mItem = item; tvItem.setText(item); } public void initListeners() { btnLocalData.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "Local Data Clicked : " + mItem, Toast.LENGTH_LONG) .show(); } }); btnOnlineData.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "Online Data Clicked : " + mItem, Toast.LENGTH_LONG) .show(); } }); } } } 
+1
source

Please use the ViewHolder template. You will need the following data:

item_listrow.xml:

 <LinearLayout android:layout_height = "match_parent"; andorid:layout_width = "match_parent"; andorid:orientation = "horizontal"; > <Button android:id = "@+id/button1" android:layout_height = "match_parent"; andorid:layout_width = "0dp"; andorid:layout_weight = 1; /> <Button android:id = "@+id/button2" android:layout_height = "match_parent"; andorid:layout_width = "0dp"; andorid:layout_weight = 1; /> </LinaerLayout> 

And your getView () method should look like this:

 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null){ LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.layout_listrow,null); Holder h = new Holder(); h.button1 = (Button) view.findViewById(R.id.button1); h.button2 = (Button) view.findViewById(R.id.button2); view.setTag(h); } Holder holder = (Holder) view.getTag(); holder.button1.setText(list.get(0)); holder.button2.setText(list.get(1)); listItemText.setText(list.get(position)); holder.button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); holder.button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); return view; } 

Holder class used above: (just insert it inside the adapter class)

 public static class Holder { Button button1; Button button2; } 

Here is the code to hide the buttons based on this isDeveloperMode() method:

 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null){ LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.layout_listrow,null); Holder h = new Holder(); h.button1 = (Button) view.findViewById(R.id.button1); h.button2 = (Button) view.findViewById(R.id.button2); view.setTag(h); } Holder holder = (Holder) view.getTag(); if(isDeveloperMode()){ holder.button1.setVisibility(View.VISIBLE); holder.button2.setVisibility(View.VISIBLE); holder.button1.setText(list.get(0)); holder.button2.setText(list.get(1)); listItemText.setText(list.get(position)); holder.button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); holder.button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); } else { holder.button1.setVisibility(View.GONE); holder.button2.setVisibility(View.GONE); } return view; } 
+1
source

Change your code on the adapter

 @Override public View getView(int position, View convertView, ViewGroup parent) { if(convertView== null){ LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView= inflater.inflate(R.layout.layout_listview,null); } Log.d("TAG", list.get(position)); TextView listItemText = (TextView) convertView.findViewById(R.id.list_item_string); listItemText.setText(list.get(position)); Button localData = (Button) convertView.findViewById(R.id.button1); Button onlineData = (Button) convertView.findViewById(R.id.button2); localData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); onlineData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); return convertView; } 
0
source

Try instead

 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null){ LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.layout_listview,null); } Log.d("TAG", list.get(position)); TextView listItemText = (TextView) view.findViewById(R.id.list_item_string); 

use

 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); Log.d("TAG", list.get(position)); TextView listItemText = (TextView) view.findViewById(R.id.list_item_string); 
0
source

Source: https://habr.com/ru/post/979610/


All Articles