Recyclerview的适配器onCreateViewHolder()方法parent.getHeight()返回0

问题描述 投票:0回答:4

我正在开发照片编辑应用程序,在其中我在回收站视图中显示贴纸。 我正在动态设置充气视图的高度和宽度,如代码所示,它在除 nougat 之外的所有 android 操作系统版本中都可以正常工作。在 nougat 中,parent.getHeight() 返回 0。我不想将高度和宽度设置为静态,而且我不想不知道我做错了什么

package com.demo.makefunnyface.Adapters;

import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.demo.makefunnyface.R;
import com.demo.makefunnyface.Utils.PojoSticker;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hp on 9/5/2017.
 */

public class AdapterSticker extends RecyclerView.Adapter<AdapterSticker.MyHolder> {

    Context context;
    List<PojoSticker> stickersList = new ArrayList<>();
    OnSelectListener onSelectListener;
    DisplayImageOptions displayImageOptions;
    ImageLoader imageLoader;
    ImageLoaderConfiguration imageLoaderConfiguration;

    public AdapterSticker(Context context, List<PojoSticker> stickersList) {
        this.context = context;
        this.stickersList.addAll(stickersList);

        displayImageOptions = new DisplayImageOptions.Builder().cacheOnDisk(true).cacheInMemory(true).build();
        imageLoaderConfiguration = new ImageLoaderConfiguration.Builder(context).defaultDisplayImageOptions(displayImageOptions).build();
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(imageLoaderConfiguration);
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_sticker_layout, parent, false);
        RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
        layoutParams.height = parent.getHeight();
        layoutParams.width = parent.getHeight();

        //nougat show zero in log
        Log.e("height", "" + parent.getHeight());
        view.setLayoutParams(layoutParams);
        return new MyHolder(view);
    }

    @Override
    public void onBindViewHolder(MyHolder holder, int position) {
        imageLoader.displayImage(stickersList.get(position).getPath(), holder.imgSticker);
    }

    @Override
    public int getItemCount() {
        return stickersList.size();
    }

    class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        ImageView imgSticker;

        public MyHolder(View itemView) {
            super(itemView);
            imgSticker = (ImageView) itemView.findViewById(R.id.imgSticker);
            imgSticker.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            PojoSticker pojoSticker = stickersList.get(getAdapterPosition());
            if (onSelectListener != null) {
                onSelectListener.onSelected(pojoSticker);
            }
        }
    }

    public interface OnSelectListener {
        void onSelected(PojoSticker pojoSticker);
    }

    public void setSelectListener(OnSelectListener onSelectListener) {
        this.onSelectListener = onSelectListener;
    }

    public int dpToPx(int dp) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        int tmp = (int) ((dp * displayMetrics.density) + 0.5);
        Log.e("tmp", "" + tmp);
        return tmp;
    }
}
android android-recyclerview
4个回答
2
投票

问题不在于onCreateViewHolder,而是你将数据添加到recyclerview(触发对象创建)的地方,因为在onCreate时你的视图没有完成测量,你必须延迟计算它,例如onResume。


0
投票

这是因为在创建时你的视图不存在。尝试在你的 onBindViewHolder 中

@Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        Log.e("height", "" + holder.itemView.getHeight());
        }

0
投票

为我工作

尝试将 RecyclerView 放入布局中,而 XML 中不包含任何其他视图,如下例所示:

<LinearLayout
    android:layout_width="200dp"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="10">

    <fr.semantic.ecare.app.android.components.utils.CustomTextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:gravity="center"
        android:id="@+id/collect_period" />

<!-- IMPORTANT TO DO -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="6">

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/recycler_view_list"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true">
        </android.support.v7.widget.RecyclerView>

    </RelativeLayout> .....
.........
</LinearLayout>

在您的活动或片段中:

@Override
    public CollectGlycaemiaViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.YOUR_XML_LAYOUT, parent, false);


        int height = parent.getMeasuredHeight() / 3 ; // if you want to devise the height exactly
        int width = parent.getMeasuredWidth();
        view.setLayoutParams(new RecyclerView.LayoutParams(width, height));

        return new CollectGlycaemiaViewHolder(view);
    }

希望它对未来的开发者有帮助


0
投票

我通过适配器的构造函数传递了屏幕宽度。

public HorizontalAdapter(HorizontalItem[] list, int screenWidth)
HorizontalAdapter adapter = new HorizontalAdapter(list, getScreenWidth())
private int getScreenWidth(){
    WindowManager windowManager = requireActivity().getWindowManager();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    windowManager.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.widthPixels;
}

并在适配器的

onCreateViewHolder
内将其设置为您想要的屏幕百分比。

例如屏幕宽度的

33%

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.viewholder_horizontal_item, parent, false);
        ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();

        //Set to the percent you want here.
        layoutParams.width = (int) (screenWidth * 0.33f);

        itemView.setLayoutParams(layoutParams);
        return new ViewHolder(itemView);
    }
© www.soinside.com 2019 - 2024. All rights reserved.