title: Samsung's ListView causing layout problems while over scrolling when there are WebViews present
body: <p>Samsung had customized <code>ListView</code> so that it has always been able to overscroll, ignoring functions like <code>setOverScrollMode()</code>. It was fine for me, until now I have layout problems associated with it. </p>
  
  <p>I need to have a <code>ListView</code> that displays normal items, and insert some in-row ads  at certain pre-defined row number, using <code>WebView</code>. To be able to re-use the code, I created a base adapter and all other adapters extend it.</p>
  
  <p><strong>InRowAdAdapter.java</strong></p>
  
  <pre><code>public class InRowAdAdapter extends BaseAdapter {
      private final Context mContext;
      private SparseArray&lt;WebView&gt; webViews;
  
      private OnInRowAdItemClickListener mListener = null;
  
      public void setOnInRowAdItemClickListener(
              OnInRowAdItemClickListener listener) {
          mListener = listener;
      }
  
      public interface OnInRowAdItemClickListener {
          public void onInRowAdItemClick(View v);
      }
  
      public InRowAdAdapter(Context context) {
          mContext = context;
          webViews = new SparseArray&lt;WebView&gt;();
      }
  
      @Override
      public int getCount() {
          return 0;
      }
  
      @Override
      public Object getItem(int position) {
          return null;
      }
  
      @Override
      public long getItemId(int position) {
          return 0;
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          final int adCount = webViews.size();
          for (int i = 0; i &lt; adCount; i++) {
              ((ViewGroup) convertView)
                      .removeView(webViews.get(webViews.keyAt(i)));
          }
  
          if (AdManager.isAdRow(position)) { // If this row is pre-defined to show ads
              if (webViews.get(position) == null) {
                  webViews.put(position, AdManager.addAd(mContext,
                          (ViewGroup) convertView, MyApp.URL_ROW_AD));
              } else {
                  try {
                      AdManager.addAd((ViewGroup) convertView,
                              webViews.get(position));
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
              webViews.get(position).setVisibility(View.VISIBLE);
              convertView.setClickable(true);
              // To fix that onItemClick() is not working
              convertView.setOnClickListener(new OnClickListener() {
  
                  @Override
                  public void onClick(View v) {
                      if (mListener != null)
                          mListener.onInRowAdItemClick(v);
                  }
  
              });
          }
          return convertView;
      }
  
      protected Context getContext() {
          return mContext;
      }
  
  }
  </code></pre>
  
  <p><strong>AdManager.java</strong></p>
  
  <pre><code>public class AdManager {
  
  
      /**
       * Create a new WebView and add it to the supplied ViewGroup.
       * 
       * @return The created WebView
       **/
      public static WebView addAd(final Context context,
              final ViewGroup container, final String adUrl) {
          final WebView webView = new WebView(context);
          webView.setVisibility(View.GONE);
          webView.loadUrl(adUrl);
          WebSettings webSettings = webView.getSettings();
          webSettings.setJavaScriptEnabled(true);
  
          // webView.setInitialScale((Math.round(adHeight / BOTTOM_AD_MIN_HEIGHT
          // * 100)) + 2);
          webView.setClickable(true);
          webView.setWebViewClient(new WebViewClient() {
  
              @Override
              public boolean shouldOverrideUrlLoading(WebView view, String url) {
                  Intent urlIntent = new Intent(
                          android.content.Intent.ACTION_VIEW, Uri.parse(url));
                  urlIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                  context.startActivity(urlIntent);
                  return true;
              }
  
          });
          addAd(container, webView);
          return webView;
      }
  
      /**
       * Add the webView to the bottom of the supplied ViewGroup. If a
       * LinearLayout is passed to this function, please make sure that its
       * orientation is vertical.
       **/
      public static void addAd(final ViewGroup container, final WebView webView) {
          if (container instanceof RelativeLayout) {
              RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                      LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
              params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
              params.addRule(RelativeLayout.BELOW,
                      container.getChildAt(container.getChildCount() - 1).getId());
              container.addView(webView, params);
          } else if (container instanceof LinearLayout) {
              LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                      LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
              container.addView(webView, params);
          }
      }
  }
  </code></pre>
  
  <p>And this is how I use it:
  <strong>MyAdapter.java</strong></p>
  
  <pre><code>public class MyAdapter extends InRowAdAdapter {
      private final List&lt;Product&gt; products;
  
      public static class ViewHolder {
          public TextView vBrand;
          public TextView vProduct;
          public SmartImageView vImage;
          public TextView vDescription;
          public String id;
      }
  
      public MyAdapter(Context context, List&lt;Product&gt; products) {
          super(context);
          this.products = products;
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          ViewHolder holder;
          if (convertView == null) {
              LayoutInflater inflater = (LayoutInflater) getContext()
                      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              convertView = inflater.inflate(
                      R.layout.adapter_product_new_arrival_list_item, null);
              holder = new ViewHolder();
              holder.vBrand = (TextView) convertView
                      .findViewById(R.id.brand_name);
              holder.vProduct = (TextView) convertView
                      .findViewById(R.id.product_name);
              holder.vImage = (SmartImageView) convertView
                      .findViewById(R.id.product_image);
              holder.vDescription = (TextView) convertView
                      .findViewById(R.id.description);
              convertView.setTag(holder);
          } else
              holder = (ViewHolder) convertView.getTag();
  
          holder.vBrand.setText(products.get(position).getBrandName());
          holder.vProduct.setText(products.get(position).getProductName());
          holder.vImage.setImageUrl(products.get(position).getImageUrl());
          holder.vDescription.setText(products.get(position).getDescription());
          holder.id = products.get(position).getProductId();
          // Let InRowAdAdapter handle the ads
          return super.getView(position, convertView, parent);
      }
  
      @Override
      public int getCount() {
          return products.size();
      }
  
      @Override
      public Object getItem(int position) {
          return products.get(position);
      }
  
      @Override
      public long getItemId(int position) {
          return position;
      }
  
  }
  </code></pre>
  
  <p>Now problem is, normally it looks like this:
  <img src="https://i.stack.imgur.com/QydEo.jpg" alt="enter image description here"></p>
  
  <p>But when over scrolled:</p>
  
  <p><img src="https://i.stack.imgur.com/yMlqm.jpg" alt="enter image description here"></p>
  
  <p>All rows are moved normally, but for some weird reasons the content of my WebView is not being scrolled. We can tell from the screenshot that the size of the WebView did not change. This only happens on Samsung devices. <strong>What on earth is happening?</strong> How can I fix this issue? I think trying to disable overscroll is not an option because Samsung wrote their own <code>ListView</code>.</p>
  
  <p>Thanks for reading this long post.</p>