Android 三星';s ListView在存在Web视图的情况下过度滚动时导致布局问题

Android 三星';s ListView在存在Web视图的情况下过度滚动时导致布局问题,android,android-listview,android-webview,samsung-mobile,Android,Android Listview,Android Webview,Samsung Mobile,三星已经定制了ListView,因此它总是能够进行overscroll,而忽略了setOverScrollMode()等函数。这对我来说很好,直到现在我都有与之相关的布局问题 我需要一个显示普通项目的列表视图,并使用WebView在某些预定义的行号插入一些行内广告。为了能够重用代码,我创建了一个基本适配器,所有其他适配器都对其进行了扩展 InRowAdAdapter.java public class InRowAdAdapter extends BaseAdapter { privat

三星已经定制了
ListView
,因此它总是能够进行overscroll,而忽略了
setOverScrollMode()
等函数。这对我来说很好,直到现在我都有与之相关的布局问题

我需要一个显示普通项目的
列表视图
,并使用
WebView
在某些预定义的行号插入一些行内广告。为了能够重用代码,我创建了一个基本适配器,所有其他适配器都对其进行了扩展

InRowAdAdapter.java

public class InRowAdAdapter extends BaseAdapter {
    private final Context mContext;
    private SparseArray<WebView> 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<WebView>();
    }

    @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 < 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;
    }

}
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);
        }
    }
}
public class MyAdapter extends InRowAdAdapter {
    private final List<Product> 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<Product> 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;
    }

}
我就是这样使用它的: MyAdapter.java

public class InRowAdAdapter extends BaseAdapter {
    private final Context mContext;
    private SparseArray<WebView> 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<WebView>();
    }

    @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 < 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;
    }

}
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);
        }
    }
}
public class MyAdapter extends InRowAdAdapter {
    private final List<Product> 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<Product> 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;
    }

}
公共类MyAdapter在RowadaAdapter中扩展{
私人最终产品清单;
公共静态类视图持有者{
公共文本视图vBrand;
公共文本视图VPProduct;
公共SmartImageView vImage;
公共文本视图描述;
公共字符串id;
}
公共MyAdapter(上下文、列表产品){
超级(上下文);
这一点。产品=产品;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视窗座;
if(convertView==null){
LayoutInflater充气器=(LayoutInflater)getContext()
.getSystemService(上下文布局\充气机\服务);
convertView=充气机。充气(
R.layout.adapter\u product\u new\u arrival\u list\u item,空);
holder=新的ViewHolder();
holder.vBrand=(TextView)convertView
.findviewbyd(R.id.品牌名称);
holder.vpproduct=(TextView)convertView
.findViewById(R.id.产品名称);
holder.vImage=(SmartImageView)convertView
.findViewById(R.id.product_图像);
holder.vDescription=(TextView)convertView
.findViewById(R.id.说明);
convertView.setTag(支架);
}否则
holder=(ViewHolder)convertView.getTag();
holder.vBrand.setText(products.get(position.getBrandName());
holder.vpproduct.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();
//让InRowadaAdapter来处理广告
返回super.getView(position、convertView、parent);
}
@凌驾
public int getCount(){
返回产品。大小();
}
@凌驾
公共对象getItem(int位置){
退货。获得(职位);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
}
现在的问题是,通常看起来是这样的:

但是,当过卷时:

所有行都会正常移动,但由于一些奇怪的原因,我的WebView的内容不会被滚动。我们可以从截图上看出,WebView的大小没有改变。这只发生在三星设备上到底发生了什么事?我如何解决这个问题?我认为尝试禁用overscroll不是一个选项,因为三星自己编写了
ListView


感谢您阅读这篇长篇文章。

关于三星在其设备上定制
Overscroll
的说法是正确的。我在尝试编写一个覆盖
onoverscroll()
方法的
overscrollView
时遇到了类似的问题

我不知道它是否有效,但很有可能下载
ListView的
并在应用程序中使用它可以解决您的问题

祝你好运