If you are developing an Android application, you will definitely meet "Hell to bite a custom Adapter into a ListView"
It wouldn't be possible once it was implemented. This time, I'd like to go further and put a Button inside the ListView.
Surprisingly, there are many scenes like this, right? A checkBox, a Button for editing or deleting.
This time I would like to do my best to make the UI below. It's a substitute for a personal memo.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String[] countries = {
"America",
"Japan",
"China",
"Korea",
"British",
"German"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
CustomAdapter adapter = new CustomAdapter(getApplicationContext(), R.layout.row_item, countries);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (view.getId()) {
case R.id.edit:
Toast.makeText(MainActivity.this, countries[position] + "Edit button was pressed", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(MainActivity.this, countries[position] + "The delete button was pressed", Toast.LENGTH_SHORT).show();
break;
}
}
});
}
}
main_activity.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"
tools:context="hiroto.myapplication.MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/gray"
android:dividerHeight="1dp"/>
</LinearLayout>
This time, only ListView is prepared for MainActivity. We are configuring a custom ListView that displays the text with two buttons by biting the ListView with the custom Adapter introduced below.
The caveat here is to give the ListView a SetOnItemClickListener
to get the click event from the Adapter side. Don't forget ...
To determine which button the acquired event is, it is implemented by specifying the id in the switch statement.
CustomAdapter.java
class CustomAdapter extends BaseAdapter {
private LayoutInflater inflater;
private int resourcedId;
private String[] items;
static class ViewHolder {
Button editButton;
TextView textView;
Button deleteButton;
}
CustomAdapter(Context context, int resourcedId, String[] items) {
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.resourcedId = resourcedId;
this.items = items;
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(resourcedId, parent, false);
holder = new ViewHolder();
holder.editButton = convertView.findViewById(R.id.edit);
holder.textView = convertView.findViewById(R.id.text);
holder.deleteButton = convertView.findViewById(R.id.delete);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(items[position]);
holder.editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((ListView) parent).performItemClick(view, position, R.id.edit);
}
});
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((ListView) parent).performItemClick(view, position, R.id.delete);
}
});
return convertView;
}
@Override
public int getCount() {
return items.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
}
row_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="horizontal">
<Button
android:id="@+id/edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="Edit"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="30dp"
android:layout_toEndOf="@+id/edit"/>
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="Delete"/>
</RelativeLayout>
In the custom Adapter, the part to be displayed in each line is acquired by findById
, the text is the country name bysetText ()
, the button covers SetOnClickListener
with performeItemClick
, and the event is sent to the parent ListView. This method is the most recommended as it is relatively simple and does not interfere with other code.
What did you think? There are various ways to get the events in the ListView, but the one I introduced this time is the simplest, and I think it's easy to introduce because it doesn't have to be modified from the original code. Also, the flow is not so complicated, so I think it was easy to understand.
I hope it will be helpful to everyone.
Recommended Posts