RecyclerView获取项目位置以动态设置项目LayoutParams

时间:2017-01-18 22:26:11

标签: android android-recyclerview


我正在创建一个具有多种视图类型的 RecyclerView 在RecyclerView数据集(mResults)中,我有多个TYPE_WEB项 此类型的每个项目都有一个特定的视图height 我的问题是:
在方法OnCreateViewHolder()中,我告诉适配器要膨胀的viewHolder类型以及我可以将LayoutParams应用于膨胀的视图,我似乎无法获得{{1}的位置膨胀。我需要项目位置,以便从数据集中指定索引处的对象获取相关高度 如果我解释的不清楚,我会举一个简短的例子:
假设我的数据集中有itemViewHolder的3项,索引为2,4,7 每个都有一个独特的高度 我需要告诉适配器,如果项目是TYPE_WEB,请从数据集中获取相关索引处的对象,获取它的高度,并应用于TYPE_WEB

我的代码:

LayoutParams

我尝试过的解决方案无效:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

public static final int TYPE_ARTICLE = 1;
public static final int TYPE_WEB = 2;

private Context mContext;
private MyFragmentManager mListener;
private ArrayList<ItemObjectResult> mResults;
private GeneralUtils mGeneralUtils;

//------------------------------------ Constructor ---------------------------------------------

public RecyclerViewAdapter(Context mContext, ArrayList<ItemObjectResult> mArticles) {
    this.mContext = mContext;
    this.mResults = mArticles;
    this.mListener = (MyFragmentManager) mContext;
    this.mGeneralUtils = new GeneralUtils(mContext);
}

//------------------------------------ Listeners methods ---------------------------------------

@Override //RecyclerView.Adapter<RecyclerView.ViewHolder>
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View convertView;

    switch (viewType) {

        case TYPE_ARTICLE:
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main_feed_article, parent, false);
            RecyclerView.LayoutParams articleLp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mGeneralUtils.dpToPx(280));
            convertView.setLayoutParams(articleLp);
            return new ArticleViewHolder(convertView);


        case TYPE_WEB:
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main_feed_web, parent, false);

            /** Get the height of this TYPE_WEB item , int viewHeight = mResults.get(itemPosition).getHeight();
                Create new LayoutParams with the height we got from the item
                Apply the height of this specific web item to it's view */

            RecyclerView.LayoutParams webLp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            convertView.setLayoutParams(webLp);
            return new WebViewHolder(convertView);

    }
    return null;
}

@Override //RecyclerView.Adapter<RecyclerView.ViewHolder>
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    switch (holder.getItemViewType()) {
        case TYPE_ARTICLE:
            ArticleViewHolder articleViewHolder = (ArticleViewHolder) holder;
            configureArticleVH(articleViewHolder, position);
            break;

        case TYPE_WEB:
            final WebViewHolder webViewHolder = (WebViewHolder) holder;
            configureWebVH(webViewHolder, position);
            break;
    }

}

@Override //RecyclerView.Adapter<RecyclerView.ViewHolder>
public int getItemViewType(int position) {

    ItemObjectResult article = mResults.get(position);

    if (article.getItemType().equals("ARTICLE"))
        return TYPE_ARTICLE;
    else if (article.getItemType().equals("web"))
        return TYPE_WEB;

   return -1;
}

@Override //RecyclerView.Adapter<RecyclerView.ViewHolder>
public int getItemCount() {
    return (null != mResults ? mResults.size() : 0);
}

//------------------------------------ Helper methods ------------------------------------------

private void configureArticleVH(ArticleViewHolder holder, int position){
    ItemObjectResult item = mResults.get(position);

    holder.url.setText(item.getWapLink());
    Picasso.with(mContext).load(item.getImage()).into(holder.mainImage);
    holder.title.setText(item.getTitle());
    holder.subtitle.setText(item.getSubtitle());
    holder.time.setText(item.getPubDate());

}

private void configureWebVH(final WebViewHolder holder, int position){

    final ItemObjectResult item = mResults.get(position);

    holder.circularProgressBar.setIndeterminateDrawable(new CircularProgressDrawable
            .Builder(mContext)
            .sweepSpeed(1f)
            .style(CircularProgressDrawable.STYLE_ROUNDED)
            .build());

    WebSettings websettings = holder.webView.getSettings();
    websettings.setJavaScriptEnabled(true);
    holder.webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(item.getWvUrl());
            return false;
        }
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            holder.circularProgressBarContainer.setVisibility(View.GONE);
        }
    });
    holder.webView.loadUrl(item.getWvUrl());
}

//------------------------------------ ViewHolder methods --------------------------------------

class ArticleViewHolder extends RecyclerView.ViewHolder {
    private TextView title, subtitle, time, url ;
    private ImageView mainImage;

    public ArticleViewHolder(View convertView) {
        super(convertView);
        this.mainImage = (ImageView) convertView.findViewById(R.id.articleMainImage);
        this.title = (TextView) convertView.findViewById(R.id.articleTitle);
        this.subtitle = (TextView) convertView.findViewById(R.id.articleSubtitle);
        this.time = (TextView) convertView.findViewById(R.id.articleTime);
        this.url = (TextView) convertView.findViewById(R.id.articleUrl);

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                 mListener.changeFragment(MyWebViewFragment.newInstance(mContext, url.getText().toString()));
            }
        });
    }

}

class WebViewHolder extends RecyclerView.ViewHolder {
    private WebView webView;
    private CircularProgressBar circularProgressBar;
    private RelativeLayout circularProgressBarContainer;

    public WebViewHolder(View convertView) {
        super(convertView);
        this.webView = (WebView) convertView.findViewById(R.id.itemWebView);
        circularProgressBar = (CircularProgressBar) convertView.findViewById(R.id.circularProgressBar);
        circularProgressBarContainer = (RelativeLayout) convertView.findViewById(R.id.circularProgressBarContainer);
    }
}

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用getAdapterPosition方法..这就是onCreateViewHolder看起来的方式

@Override //RecyclerView.Adapter<RecyclerView.ViewHolder>
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View convertView;

    switch (viewType) {

        case TYPE_ARTICLE:
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main_feed_article, parent, false);
            RecyclerView.LayoutParams articleLp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mGeneralUtils.dpToPx(280));
            convertView.setLayoutParams(articleLp);
            return new ArticleViewHolder(convertView);


        case TYPE_WEB:
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main_feed_web, parent, false);



            RecyclerView.LayoutParams webLp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

            WebViewHolder holder  = new WebViewHolder(convertView);
            int position = holder.getAdapterPosition();
            // Get height
            int viewHeight = mResults.get(position).getHeight();

            return holder;

    }
    return null;
}

此外,如果您从recyclerview getAdapterPosition添加/删除项目可能会返回RecyclerView.NO_POSITION,那么您可能需要处理该案例

修改

您还可以使用跨度为1的StaggeredGridLayoutManager。它用于处理不同高度的项目,因此您无需显式管理高度。您需要执行以下更改:

1)使row_item.xml的根布局具有layout_height = wrap_content

2)按如下方式为您的recyclerview分配交错布局管理器:

recyclerView.setLayoutManager(new StaggeredLayoutManager(1, StaggeredLayoutManager.VERTICAL))