ListView中ImageView滚动时图片消失及ListView对象显隐问题求助
Hey there! Let's break down your two ListView problems and solve them with practical fixes, tailored to your existing IzahAdapter code.
The key here is to control visibility via your data model (not directly manipulating views, since ListView reuses views aggressively). Here's how to implement it step by step:
Step 1: Add a visibility flag to your data model
Update your IzahVeriModeli class to track whether each item should be visible:
public class IzahVeriModeli { // Your existing fields (e.g., text, image URL) private boolean isVisible = true; // Default to visible // Getter and Setter public boolean isVisible() { return isVisible; } public void setVisible(boolean visible) { isVisible = visible; } }
Step 2: Update your Adapter's getView() method
Modify the getView() logic to respect the visibility flag and handle view reuse correctly:
@Override public View getView(int position, View convertView, ViewGroup parent) { // Initialize LayoutInflater if null if (layoutInflater == null) { layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } // Reuse view or inflate new one if (convertView == null) { convertView = layoutInflater.inflate(R.layout.your_item_layout, parent, false); Holder = new holder(); // Initialize your holder views here (e.g., Holder.imageView = convertView.findViewById(R.id.item_image);) convertView.setTag(Holder); } else { Holder = (holder) convertView.getTag(); } IzahVeriModeli currentItem = list.get(position); // Set visibility based on the model's flag if (currentItem.isVisible()) { convertView.setVisibility(View.VISIBLE); // Bind your data to views here (e.g., Holder.textView.setText(currentItem.getSomeText());) } else { convertView.setVisibility(View.GONE); // Clear view content to avoid reuse issues // Holder.textView.setText(""); // Holder.imageView.setImageDrawable(null); } return convertView; }
Step 3: Trigger visibility changes
To show/hide an item, update the model and notify the adapter:
// Example: Hide the 2nd item (index 1) list.get(1).setVisible(false); adapter.notifyDataSetChanged();
This issue almost always stems from nested scroll containers (ListView + ScrollView) causing layout calculation bugs and view reuse issues. Here are the best fixes:
Option 1: Remove ScrollView nesting (RECOMMENDED)
Android doesn't support nested scroll containers well. Instead, add your static content (above/below ListView) as a header/footer to the ListView:
// Add a header to your ListView View headerView = getLayoutInflater().inflate(R.layout.your_header_layout, yourListView, false); yourListView.addHeaderView(headerView); // Add a footer if needed View footerView = getLayoutInflater().inflate(R.layout.your_footer_layout, yourListView, false); yourListView.addFooterView(footerView);
Option 2: Fix the nested layout if you must keep it
If you can't remove the ScrollView, fix the ListView's height calculation and image loading:
a. Custom ListView to calculate full height
Create a custom ListView that ignores scroll limits and calculates its full height:
public class NonScrollListView extends ListView { public NonScrollListView(Context context) { super(context); } public NonScrollListView(Context context, AttributeSet attrs) { super(context, attrs); } public NonScrollListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Force ListView to measure all items' total height int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
Use this NonScrollListView in your XML layout instead of the default ListView.
b. Fix image loading for view reuse
If using a library like Glide/Picasso (always recommended for image loading), ensure you bind images correctly to avoid reuse bugs:
// Example with Glide in your Adapter's getView() Glide.with(context) .load(currentItem.getImageUrl()) // Your image URL/path .placeholder(R.drawable.placeholder_image) // Loading placeholder .error(R.drawable.error_image) // Fallback for failed loads .into(Holder.imageView);
If loading images manually, use the View's tag to avoid old loads overwriting new content:
// Manual image loading with tag check Holder.imageView.setTag(currentItem.getImageUrl()); new AsyncTask<String, Void, Bitmap>() { @Override protected Bitmap doInBackground(String... params) { // Your bitmap loading logic here return loadBitmapFromUrl(params[0]); } @Override protected void onPostExecute(Bitmap bitmap) { // Only set bitmap if the view's tag matches the current item's URL if (Holder.imageView.getTag().equals(currentItem.getImageUrl())) { Holder.imageView.setImageBitmap(bitmap); } } }.execute(currentItem.getImageUrl());
内容的提问来源于stack exchange,提问作者Coşkun Cengiz

