如何解决如何为android recyclerview中的最大字符串设置textview高度?
我有一个 Horizontal recyclerview 和适配器,在那个图片里面,然后在标题下面,然后在下面的描述。现在所有元素的图像和标题长度几乎相同,但描述可能会有所不同。所有数据均来自 API。
现在我想要做的是,我想设置所有textview-description元素的高度,其中描述长度的数量最多。
类似于这个问题:How to set recycler height to highest item in recyclerView?
但我的问题是不同的,我只是在谈论 desc textview 而不是整个 recycleeview。
请注意:由于desc较小,可以在空白区域下方显示一张cardview,但请确保desc应覆盖在具有最高字符串长度的cardview中。
代码:
public class RecommendationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE = 1;
private final Context mContext;
private final ArrayList<Attributes> attributesArrayList;
private final Resources mResources;
private final BaseActivity baseActivity;
private final OnItemClickListener listener;
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onViewItemClicked();
}
};
public RecommendationAdapter(Context mContext,ArrayList<BraAttributes> attributesArrayList,OnItemClickListener listener) {
this.mContext = mContext;
this.attributesArrayList = attributesArrayList;
mResources = mContext.getResources();
baseActivity = (BaseActivity) mContext;
this.listener = listener;
}
@NotNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NotNull ViewGroup parent,int viewType) {
View itemLayoutView;
if (viewType == VIEW_TYPE) {
itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recommend_item_layout,null);
return new ChildViewHolderItem(itemLayoutView);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewholder,int position) {
if (getItemViewType(position) == VIEW_TYPE) {
ChildViewHolderItem holder = (ChildViewHolderItem) viewholder;
final Attributes attributes = attributesArrayList.get(position);
holder.ctvTitle.setText(attributes.getName());
holder.ctvDescription.setText(attributes.getMessage());
setimage(attributes,holder);
}
}
private void findLargestString(ArrayList<attributes> attributesArrayList,CustomTextView textView) {
String res = "";
int largestString = attributesArrayList.get(0).getMessage().length();
for (int i = 0; i < attributesArrayList.size(); i++) {
if (attributesArrayList.get(i).getMessage().length() > largestString) {
largestString = attributesArrayList.get(i).getMessage().length();
res = attributesArrayList.get(i).getMessage();
}
}
LogUtils.d("Largest String: " + res);
setTextViewHeight(textView,res);
}
private void setimage(Attributes attributes,ChildViewHolderItem holder) {
if (attributes.getimage().length() > 0) {
Glide.with(holder.ivImage.getContext())
.load(IMAGE_SERVER_URL + "/medium.jpg")
.apply(new RequestOptions().error(R.drawable.default_load_image)
.placeholder(R.drawable.default_load_image))
.into(holder.ivImage);
}
}
private int getHeight(Context context,CharSequence text,int textSize,int deviceWidth,Typeface typeface,int padding) {
CustomTextView textView = new CustomTextView(context);
textView.setPadding(padding,padding,0);
textView.setTypeface(typeface);
textView.setText(text,TextView.BufferType.SPANNABLE);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,textSize);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth,View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
textView.measure(widthMeasureSpec,heightMeasureSpec);
return textView.getMeasuredHeight();
}
private void setTextViewHeight(CustomTextView ctvDescription,String largestString) {
int deviceWidth;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
displayMetrics displayMetrics = new displayMetrics();
wm.getDefaultdisplay().getMetrics(displayMetrics);
deviceWidth = displayMetrics.widthPixels;
LogUtils.d("deviceWidth: " + deviceWidth); //1080
int padding = mContext.getResources().getDimensionPixelSize(R.dimen.dimen_15);
int height = getHeight(mContext,largestString,mContext.getResources().getDimensionPixelSize(R.dimen.textsize_12),deviceWidth,Typeface.DEFAULT,padding);
ctvDescription.setHeight(AppUtils.pxToDp(mContext,height));
}
@Override
public int getItemCount() {
return Math.max(attributesArrayList.size(),0);
}
@Override
public int getItemViewType(int position) {
return VIEW_TYPE;
}
public class ChildViewHolderItem extends RecyclerView.ViewHolder {
@BindView(R.id.ivImage)
AppCompatimageView ivImage;
@BindView(R.id.ctvTitle)
CustomTextView ctvTitle;
@BindView(R.id.ctvDescription)
CustomTextView ctvDescription;
public ChildViewHolderItem(View v) {
super(v);
ButterKnife.bind(this,v);
v.setonClickListener(onClickListener);
findLargestString(attributesArrayList,ctvDescription);
}
}
}
解决方法
更新
根据记者的要求更新更多答案,因为她希望按照最大的描述以相同的高度和最高的高度显示所有视图。
我在代码中做了几个星期。
创建了一个方法来计算 textView 的投影高度,通过尝试列表中的所有描述来获取最高高度。
public static int getHeightOfLargestDescription(final Context context,final CharSequence text,TextView textView) {
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Point displaySize = new Point();
wm.getDefaultDisplay().getSize(displaySize);
final int deviceWidth = displaySize.x;
textView.setTypeface(Typeface.DEFAULT);
textView.setText(text,TextView.BufferType.SPANNABLE);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth,View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
textView.measure(widthMeasureSpec,heightMeasureSpec);
return textView.getMeasuredHeight();
}
然后在 onCreateViewHolder
中使用此方法准备绑定视图时要使用的最高高度。
MyViewHolder myViewHolder = new MyViewHolder(itemView);
for (Model m : modelList) {
currentItemHeight = getHeightOfLargestDescription(context,m.description,myViewHolder.description);
if (currentItemHeight > highestHeight) {
highestHeight = currentItemHeight;
}
}
然后在 onBindViewHolder` 中使用这个 highestHeight
来设置描述 TexView 的高度,这样所有的视图总是具有相同的高度,等于最高高度。
viewHolder.description.setHeight(highestHeight);
代码在同一个 repo 中提交
以前的解决方案 我已经为您的问题创建了解决方案并在 GitHub 中提交 https://github.com/dk19121991/HorizontalRecyclerWithDynamicHeight
让我分享一下解决方案的要点
您可以在 BindViewHolder 上获取描述视图的高度并存储它以检查它是否最高,并始终将新视图的高度设置为您目前获得的最高高度。
viewHolder.description.post(new Runnable() {
@Override
public void run() {
currentItemHeight = viewHolder.description.getMeasuredHeight();
if (currentItemHeight > highestHeight) {
highestHeight = currentItemHeight;
/** this is needed to make sure already inflated view with small description also get resized to largest view till now
*and this be called only if the new view is of larger size then all of the view inflated till now
*/
notifyDataSetChanged();
}
viewHolder.description.setHeight(highestHeight);
}
});
您可能会有疑问,如果已经创建的旧视图较小,而要处理的新视图会因大描述而较大。
完全不用担心。为了解决这个问题,每当我们遇到新的最高高度时,我都添加了 notifyDataSetChanged();
,这将确保所有旧视图也获得新的更大的高度。
单击此按钮可查看应用程序的运行情况 https://github.com/dk19121991/HorizontalRecyclerWithDynamicHeight/blob/master/runningSample.gif
如果这能解决您的问题,请告诉我,如果您还有其他问题,请随时提出。
谢谢
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。