不依赖onItemClickListener获取ListView多字段项值及跨Activity传递方法
Got it, let's break down your two questions step by step based on your components (LanguageActivity, LanguageAdapter, LanguageData):
The key here is that all your ListView's data is already stored in your data source (the list of LanguageData objects you passed to the adapter). You don't need to collect data by clicking each item—you can directly access this source list and pass it via Intent.
Step 1: Make sure your adapter holds the full data list
Add a method in your LanguageAdapter to expose the underlying data list:
public class LanguageAdapter extends BaseAdapter { private List<LanguageData> mLanguageList; private Context mContext; // Constructor public LanguageAdapter(Context context, List<LanguageData> languageList) { this.mContext = context; this.mLanguageList = languageList; } // Method to get the full data list public List<LanguageData> getFullLanguageList() { return mLanguageList; } // Rest of your adapter methods (getCount, getItem, getItemId, getView)... }
Step 2: Make LanguageData serializable for Intent transfer
To pass the list between activities, your LanguageData class needs to implement either Serializable or Parcelable (Serializable is simpler for basic cases):
public class LanguageData implements Serializable { private String languageName; private String languageCode; // Add any other fields you have // Constructor, getters and setters public LanguageData(String name, String code) { this.languageName = name; this.languageCode = code; } public String getLanguageName() { return languageName; } public void setLanguageName(String name) { this.languageName = name; } // Same for languageCode and other fields }
Step 3: Pass the list from LanguageActivity to target Activity
When you need to send the data (e.g., on a button click), grab the list from the adapter and put it into an Intent:
// In LanguageActivity Button sendBtn = findViewById(R.id.btn_send_data); sendBtn.setOnClickListener(v -> { LanguageAdapter adapter = (LanguageAdapter) yourListView.getAdapter(); List<LanguageData> allItems = adapter.getFullLanguageList(); Intent intent = new Intent(LanguageActivity.this, TargetActivity.class); intent.putExtra("KEY_ALL_LANGUAGE_DATA", (Serializable) allItems); startActivity(intent); });
Step 4: Receive the data in the target Activity
Retrieve the list from the Intent in your target Activity:
// In TargetActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_target); List<LanguageData> receivedData = (List<LanguageData>) getIntent().getSerializableExtra("KEY_ALL_LANGUAGE_DATA"); // Now you can use receivedData to access all ListView items' data }
Since each ListView item contains interactive views (like EditText), you need to link the input values back to your LanguageData objects. Here are two reliable approaches:
Approach 1: Update data in real-time (Recommended)
Use a TextWatcher on the EditText in your adapter's getView method to update the corresponding LanguageData object as the user types. This ensures your data source is always in sync with the UI.
Update your adapter's getView method and ViewHolder:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.language_item_layout, parent, false); holder = new ViewHolder(); holder.languageNameEt = convertView.findViewById(R.id.et_language_name); holder.languageCodeEt = convertView.findViewById(R.id.et_language_code); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } LanguageData currentData = mLanguageList.get(position); // Set initial text for EditTexts holder.languageNameEt.setText(currentData.getLanguageName()); holder.languageCodeEt.setText(currentData.getLanguageCode()); // Remove existing TextWatchers to avoid duplicate callbacks holder.languageNameEt.removeTextChangedListener(holder.nameTextWatcher); holder.languageCodeEt.removeTextChangedListener(holder.codeTextWatcher); // TextWatcher for language name EditText holder.nameTextWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { currentData.setLanguageName(s.toString()); } @Override public void afterTextChanged(Editable s) {} }; holder.languageNameEt.addTextChangedListener(holder.nameTextWatcher); // TextWatcher for language code EditText holder.codeTextWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { currentData.setLanguageCode(s.toString()); } @Override public void afterTextChanged(Editable s) {} }; holder.languageCodeEt.addTextChangedListener(holder.codeTextWatcher); return convertView; } // Updated ViewHolder with TextWatcher references static class ViewHolder { EditText languageNameEt; EditText languageCodeEt; TextWatcher nameTextWatcher; TextWatcher codeTextWatcher; }
To get the value of a single item later, just pull it from your data source:
// Get data for the 3rd item (index 2) LanguageData itemData = adapter.getFullLanguageList().get(2); String nameValue = itemData.getLanguageName(); String codeValue = itemData.getLanguageCode();
Approach 2: Fetch values directly from visible items
If you don't need real-time sync, you can retrieve values directly from the visible item views. Note: This only works for items currently on the screen (getChildAt returns null for off-screen items).
// In LanguageActivity, get value for a specific position int targetPosition = 1; // Example position View itemView = yourListView.getChildAt(targetPosition - yourListView.getFirstVisiblePosition()); if (itemView != null) { EditText nameEt = itemView.findViewById(R.id.et_language_name); EditText codeEt = itemView.findViewById(R.id.et_language_code); String nameValue = nameEt.getText().toString(); String codeValue = codeEt.getText().toString(); // Optional: Update the data source with the fetched values adapter.getFullLanguageList().get(targetPosition).setLanguageName(nameValue); adapter.getFullLanguageList().get(targetPosition).setLanguageCode(codeValue); }
内容的提问来源于stack exchange,提问作者Saad Zahoor

