自定义单元格中列表视图中按钮的点击监听器

huangapple go评论77阅读模式
英文:

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(), &quot;delete me&quot;, 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&lt;String&gt; {
    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(), &quot;delete me&quot;, 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&lt;String[]&gt; mainObjectsArray = new ArrayList&lt;String[]&gt;();
    //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&#39;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&lt;String&gt; theNames = new ArrayList&lt;String&gt;();

    @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&lt;ParseObject&gt; query = ParseQuery.getQuery(&quot;Orders&quot;);
        query.orderByDescending(&quot;updatedAt&quot;);
        query.findInBackground(new FindCallback&lt;ParseObject&gt;() {
            @Override
            public void done(List&lt;ParseObject&gt; objects, ParseException e) {
                if (e == null) {
                    //Log.i(&quot;findInBackground&quot;, &quot;Retrieved: &quot; + objects.size() + &quot;objects&quot;);
                    if (objects.size() &gt; 0) {
                        for (ParseObject object: objects) {

                            // Converting every object to an array of two itmes, title and body.
                            String[] artical = {object.getString(&quot;TheSavedOrder&quot;), object.getString(&quot;mobileNumber&quot;), object.getString(&quot;Name&quot;)};

                            // Adding the array to our main array so we will have an array of arrays
                            mainObjectsArray.add(artical);

                            //Log.i(&quot;This my family array: &quot;, 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 &lt; mainObjectsArray.size(); i++){
                            theNames.add(mainObjectsArray.get(i)[2]);
                            //Log.i(&quot;Here are teh title: &quot;, myFamily.get(i)[0]);
                            Log.i(&quot;Here is thti: &quot;, 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&lt;?&gt; parent, View view, int position, long id) {
                //Log.i(&quot;The body is: &quot;, mainObjectsArray.get(position));
                Intent intent = new Intent(getContext(), TheBody.class);
                intent.putExtra(&quot;mobile&quot;, mainObjectsArray.get(position)[1]);  // mainObjectsArray.get(position)[1] means we will pass the second item in every array which is the (mobileNumber).
                intent.putExtra(&quot;order&quot;, mainObjectsArray.get(position)[0]);
                startActivity(intent);
            }
        });

        return rootView;

    }


    // Our adapter class
    class MyAdapter extends ArrayAdapter&lt;String&gt; {
        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(), &quot;delete me&quot;, Toast.LENGTH_SHORT).show();
                }
            });
            return row;
        }
        
    }


}

This is the XML code of the fragment

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;&gt;


    &lt;ListView
        android:id=&quot;@+id/myListView&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot; /&gt;
&lt;/LinearLayout&gt;

And finally this is the XML code of the customised cell

 &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:orientation=&quot;horizontal&quot;
    android:padding=&quot;16dp&quot;
    android:descendantFocusability=&quot;blocksDescendants&quot;&gt;


    &lt;TextView
        android:id=&quot;@+id/customerName&quot;
        android:layout_width=&quot;200dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;custoemr name&quot;
        android:textColor=&quot;#000&quot;
        android:layout_margin=&quot;5dp&quot;
        android:textSize=&quot;20sp&quot;/&gt;
    &lt;Button
        android:id=&quot;@+id/deleteButton&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;Delete&quot;


    /&gt;

&lt;/LinearLayout&gt;

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(), &quot;delete me&quot;, 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&lt;MainObjects&gt; mainObjectsList = new ArrayList&lt;&gt;();
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&lt;ParseObject&gt; query = ParseQuery.getQuery(&quot;Orders&quot;);
    query.orderByDescending(&quot;updatedAt&quot;);
    query.findInBackground(new FindCallback&lt;ParseObject&gt;() {
        @Override
        public void done(List&lt;ParseObject&gt; objects, ParseException e) {
            if (e == null) {
                //Log.i(&quot;findInBackground&quot;, &quot;Retrieved: &quot; + objects.size() + &quot;objects&quot;);
                if (objects.size() &gt; 0) {
                    for (ParseObject object : objects) {
                        // Converting every object to an array of two items, title and body.
                        //String[] artical = {object.getString(&quot;TheSavedOrder&quot;), object.getString(&quot;mobileNumber&quot;), object.getString(&quot;Name&quot;)};
                        MainObjects article = new MainObjects(object.getString(&quot;TheSavedOrder&quot;), object.getString(&quot;mobileNumber&quot;), object.getString(&quot;Name&quot;);
                        // Adding the array to our main array so we will have an array of arrays
                        mainObjectsList.add(article);

                        //Log.i(&quot;This my family array: &quot;, 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&lt;?&gt; parent, View view, int position, long id) {
            //Log.i(&quot;The body is: &quot;, mainObjectsList.get(position));
            Intent intent = new Intent(getContext(), TheBody.class);
            intent.putExtra(&quot;mobile&quot;, mainObjectsList.get(position).getMobileNumber());
            intent.putExtra(&quot;order&quot;, mainObjectsList.get(position).getSavedOrder());
            startActivity(intent);
        }
    });
    return rootView;
}

class MainObjects {
    String savedOrder = &quot;&quot;, mobileNumber = &quot;&quot;, name = &quot;&quot;;

    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&lt;MainObjects&gt; {
    Context context;
    LayoutInflater inflater;
    ArrayList&lt;MainObjects&gt; rNames;

    MyAdapter(Context c, ArrayList&lt;MainObjects&gt; 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 = &quot;Delete: &quot; + pos + &quot;. &quot; + getItem(pos).getName() + &quot; !!&quot;;
                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;
    }
}

}

huangapple
  • 本文由 发表于 2020年9月16日 06:40:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63910752.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定