Specific OnItemClick Intent Android

2019-09-11 10:09发布

问题:

I want the following to happen (a simple idea): I click an Add button in my main activity, enter some info(into EditText boxes), and go back to the main screen. Here, I want to display a list, with just two titles(not all the info). When I click that list Item, I want to show the corresponding saved info for that item. Therefore, each item's info is going to be different.

When I do this, I use startActivityForResult() from the main screen then back. This works perfectly for one item. When I add another item, the problem arises. No matter which item I click, the info displayed is the same. In short, I need to find a way to save that info unique to each item.

As of now, I have the following code snippet :

 //After I add all the information in the second intent

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == 1) {
        //these display in the list (Each list item has two textfields,row1 and row 2)

        row1 = data.getStringExtra("com.painLogger.row1");
        row2 = data.getStringExtra("com.painLogger.row2");

           //below is the other info entered

        painLevelString = data.getStringExtra("com.painLogger.painLevel");
        painLocation = data.getStringExtra("painLocation");
        timeOfPainString = data.getStringExtra("com.painLogger.painTime");
        textTreatmentString = data
                .getStringExtra("com.painLogger.treatment");
        addItem();
    }
}

    //When I click the item-- this is the info that is not unique...
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
    Intent intent = new Intent(this, Item1.class);
    intent.putExtra("com.painLogger.painLevel", painLevelString);
    intent.putExtra("com.painLogger.painTime" , timeOfPainString);
    intent.putExtra("com.painLogger.treatment", textTreatmentString);
    intent.putExtra("painLocation", painLocation);
    startActivity(intent);
}

// EDIT :ADD ITEM CODE ADDED

private void addItem() {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("row_1", row1);
    map.put("row_2", row2);
    painItems.add(map);
    adapter.notifyDataSetChanged();

}

//*EDIT: some defining *

SimpleAdapter adapter;
List<HashMap<String, String>> painItems = new ArrayList<HashMap<String, String>>();

I can understand why this is occuring-- every time I click an item, the intent is putting the last extra, meaning the last object's info added. How do I make each OnItemClick unique? I suspect I will have to use the position variable.

回答1:

Two recommendations:

Pass the data to your method instead of using class fields:

addItem(String row1, String row2...){...}

Also, you want to grab your data out of the map:

public void onItemClick(AdapterView<?> a, View v, int position, long id) {
    Intent intent = new Intent(this, Item1.class);
    intent.putExtra("com.painLogger.painLevel", painItems.get(position).get("row_1"));
    intent.putExtra("com.painLogger.painTime" , painItems.get(position).get("row_2"));
    intent.putExtra("com.painLogger.treatment", painItems.get(position).get("row_3"));
    intent.putExtra("painLocation", painItems.get(position).get("row_4"));
    startActivity(intent);
}

You will of course need to put "row_3" and "row_4" into the map as you create it, which I believe you are not yet doing.

DMon suggested in a comment in a different answer that you create a class that represents your data, and he is right, it is much better design and helps save on these problems. To do so you will need to look at the Parcelable interface to be able to pass your class through Intents. Your design will work, but it will be very difficult to understand for the next guy (including you in 6 months) and much more difficult to extend.



回答2:

It's hard to tell without seeing your addItem() code, how are you adding the items to the list? Presumably you have an adapter where the values are stored, if so, then in the onItemClick(), you would do painItem = adapter.getItem(position). You would then assemble your Intent using this painItem object.



回答3:

The reason this is occurring is that the information sent in onItemClick is in no way based on which row was clicked - It's based on the most recent values set in onActivityResult, which are set by the last item clicked.

One solution would be to use a modified version of the ViewHolder pattern to attach row-specific values to the View, and then in onItemClick retrieve those values using view.getTag. Good sample code for the ViewHolder pattern can be found here. It's typically for storing Views so that they're not continually recreated & re-inflated, but it can also be used for passing values to click handlers without needing to keep track of member variable state.