英文:
Click listener for a button in a customised cell in a list view
问题
我为我的Android应用程序创建了一个自定义的列表视图,以便为每个单元格添加一个删除按钮,使用户能够从列表中删除行。自定义的列表视图工作正常,但是当我为按钮添加了点击监听器后,列表视图显示空单元格,而不是填充来自数组的数据。
以下是getView
方法的代码:
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "删除我", Toast.LENGTH_SHORT).show();
}
});
return row;
}
我认为我应该返回其他内容,而不是row
,但我不知道应该返回什么。当我思考时,当我返回row
时,它应该显示填充有数据的行。注意,当我删除这段代码时,列表视图能够正常显示数据。
以下是适配器类的整个代码:
// 我们的适配器类
class MyAdapter extends ArrayAdapter<String> {
Context context;
String rNames[];
MyAdapter(Context c, String name[]) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "删除我", Toast.LENGTH_SHORT).show();
}
});
return row;
}
}
这是主页片段页面的整个代码:
public class HomeFragment extends Fragment {
// ... (其他代码)
// 我们的适配器类
class MyAdapter extends ArrayAdapter<String> {
Context context;
String rNames[];
MyAdapter(Context c, String name[]) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "删除我", Toast.LENGTH_SHORT).show();
}
});
return row;
}
}
// ... (其他代码)
}
这是自定义单元格的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="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="@+id/customerName"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="客户姓名"
android:textColor="#000"
android:layout_margin="5dp"
android:textSize="20sp"/>
<Button
android:id="@+id/deleteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除"/>
</LinearLayout>
希望这些代码能够帮助你解决问题。如果你有任何疑问,请随时提问。
英文:
I've created a customised list view for my Android app in order to add a Delete button for every cell to make the user able to delete rows from the list. The customised list view is working well but when I added a click listener for the button, the list view show empty cells instead of populating the data coming from the array.
Here is the getView code:
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
}
});
return row;
}
I think the I should return something else not the row, but I have no idea what to return. When I think about it when I return the row it should show the rows filled with data. Note when I delete this piece of code, the list view is working well with showing the data.
This is the whole code of the adapter class
// Our adapter class
class MyAdapter extends ArrayAdapter<String> {
Context context;
String rNames[];
MyAdapter(Context c, String name[]) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
}
});
return row;
}
}
And this is the whole code of the home fragment page
public class HomeFragment extends Fragment {
// creating an empty array. This is an array of objects (array of arrays).
final ArrayList<String[]> mainObjectsArray = new ArrayList<String[]>();
//final String[][] myFamily = new String[][];
// creating another array of the titles. If our main array is an array of strings we will not need this.
// Why?. ArrayAdapter doesn't accept an array of arrays it only accepts an array of Stings, so we had to create a special array for the titles and bring them from our main array.
final ArrayList<String> theNames = new ArrayList<String>();
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_home, null);
// creaing a list view and connect it to the list view we created in the XML file
// Note: we need to add (final) to be able to access them from inside the loop
final ListView myListView = (ListView) rootView.findViewById(R.id.myListView);
// Retrieving the data and filling the array with it
ParseQuery<ParseObject> query = ParseQuery.getQuery("Orders");
query.orderByDescending("updatedAt");
query.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
//Log.i("findInBackground", "Retrieved: " + objects.size() + "objects");
if (objects.size() > 0) {
for (ParseObject object: objects) {
// Converting every object to an array of two itmes, title and body.
String[] artical = {object.getString("TheSavedOrder"), object.getString("mobileNumber"), object.getString("Name")};
// Adding the array to our main array so we will have an array of arrays
mainObjectsArray.add(artical);
//Log.i("This my family array: ", myFamily.toString());
}
// We will add only the names to the array (theNames). theTitles will be an array of strings so we can populate it in the list view.
for (int i = 0; i < mainObjectsArray.size(); i++){
theNames.add(mainObjectsArray.get(i)[2]);
//Log.i("Here are teh title: ", myFamily.get(i)[0]);
Log.i("Here is thti: ", theNames.get(i));
}
// Converting theNames from ArrayList to an array
String[] namesArray = new String[theNames.size()];
namesArray = theNames.toArray(namesArray);
// Applaying our adapter
MyAdapter adapter = new MyAdapter(getActivity(), namesArray);
myListView.setAdapter(adapter);
}
}
}
});
// When clicking on an item in the list view
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Log.i("The body is: ", mainObjectsArray.get(position));
Intent intent = new Intent(getContext(), TheBody.class);
intent.putExtra("mobile", mainObjectsArray.get(position)[1]); // mainObjectsArray.get(position)[1] means we will pass the second item in every array which is the (mobileNumber).
intent.putExtra("order", mainObjectsArray.get(position)[0]);
startActivity(intent);
}
});
return rootView;
}
// Our adapter class
class MyAdapter extends ArrayAdapter<String> {
Context context;
String rNames[];
MyAdapter(Context c, String name[]) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
}
});
return row;
}
}
}
This is the XML code of the fragment
<?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">
<ListView
android:id="@+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
And finally this is the XML code of the customised cell
<?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="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="@+id/customerName"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="custoemr name"
android:textColor="#000"
android:layout_margin="5dp"
android:textSize="20sp"/>
<Button
android:id="@+id/deleteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
/>
</LinearLayout>
Please help I've been struggling with this for some days!
Many thanks.
答案1
得分: 0
public View getView(final int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
} });
return row;
}
请注意,您的列表 rNames 是一个固定大小的数组,不能删除单个项目。如果要实现删除功能,您应该使用 ArrayList。
英文:
public View getView(final int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
} });
return row;
}
Pls also note that your list, rNames, is an array[] that is fixed size and cannot remove an individual item. You should use ArrayList if you want to implement the delete function.
Updated:
public class HomeFragment extends Fragment {
// creating an empty array. This is an array of objects (array of arrays).
ArrayList<MainObjects> mainObjectsList = new ArrayList<>();
ListView myListView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, null);
// creaing a list view and connect it to the list view we created in the XML file
// Note: we need to add (final) to be able to access them from inside the loop
myListView = (ListView) rootView.findViewById(R.id.myListView);
// Retrieving the data and filling the array with it
ParseQuery<ParseObject> query = ParseQuery.getQuery("Orders");
query.orderByDescending("updatedAt");
query.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
//Log.i("findInBackground", "Retrieved: " + objects.size() + "objects");
if (objects.size() > 0) {
for (ParseObject object : objects) {
// Converting every object to an array of two items, title and body.
//String[] artical = {object.getString("TheSavedOrder"), object.getString("mobileNumber"), object.getString("Name")};
MainObjects article = new MainObjects(object.getString("TheSavedOrder"), object.getString("mobileNumber"), object.getString("Name");
// Adding the array to our main array so we will have an array of arrays
mainObjectsList.add(article);
//Log.i("This my family array: ", myFamily.toString());
}
// Applying our adapter
MyAdapter adapter = new MyAdapter(getActivity(), mainObjectsList);
myListView.setAdapter(adapter);
}
}
}
});
// When clicking on an item in the list view
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Log.i("The body is: ", mainObjectsList.get(position));
Intent intent = new Intent(getContext(), TheBody.class);
intent.putExtra("mobile", mainObjectsList.get(position).getMobileNumber());
intent.putExtra("order", mainObjectsList.get(position).getSavedOrder());
startActivity(intent);
}
});
return rootView;
}
class MainObjects {
String savedOrder = "", mobileNumber = "", name = "";
public MainObjects(String savedOrder, String mobileNumber, String name) {
this.savedOrder = savedOrder;
this.mobileNumber = mobileNumber;
this.name = name;
}
public String getSavedOrder() {
return savedOrder;
}
public String getMobileNumber() {
return mobileNumber;
}
public String getName() {
return name;
}
}
class MyAdapter extends ArrayAdapter<MainObjects> {
Context context;
LayoutInflater inflater;
ArrayList<MainObjects> rNames;
MyAdapter(Context c, ArrayList<MainObjects> name) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
inflater = getLayoutInflater();
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = inflater.inflate(R.layout.row, parent, false);
TextView nameTv = (TextView) row.findViewById(R.id.customerName);
nameTv.setText(getItem(position).getName());
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int pos = (int)view.getTag();
String msg = "Delete: " + pos + ". " + getItem(pos).getName() + " !!";
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
rNames.remove(pos);
notifyDataSetChanged();
//
// Codes to update permanent storage, e.g. files/server/db.
//
} });
deleteButt.setTag(position);
return row;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论