android - Android 以编程方式使用 ConstraintLayout 添加 ImageView
问题描述
我想使用 ConstraintLayout 以编程方式将几个 ImageView 插入到 RecyclerView 中。
要使用水平偏置以等距方式插入图像,每个图像的值计算如下:
float biasedValue = (1f / (flightPlanWeather.weather.size () + 1f)) * (i + 1f);
代码如下
public class FlightPlanWeatherRecyclerAdapter extends RecyclerView.Adapter<FlightPlanWeatherRecyclerAdapter.MyViewHolder> {
private static final String TAG = FlightPlanWeatherRecyclerAdapter.class.getName();
private List<FlightPlanWeather> dataSet;
private LayoutInflater mInflater;
Context mContext;
// Provide a suitable constructor (depends on the kind of dataset)
// data is passed into the constructor
public FlightPlanWeatherRecyclerAdapter(Context context, List<FlightPlanWeather> data) {
this.mInflater = LayoutInflater.from(context);
this.dataSet = data;
this.mContext = context;
}
// inflates the row layout from xml when needed
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.row_item_flightplan_weather, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.bind(dataSet.get(position));
FlightPlanWeather flightPlanWeather = dataSet.get(position);
holder.from_img.setImageResource(flightPlanWeather.from.getImg_resource());
holder.from_label.setText(flightPlanWeather.from.getLabel());
holder.to_img.setImageResource(flightPlanWeather.to.getImg_resource());
holder.to_label.setText(flightPlanWeather.to.getLabel());
int dimensionInPixel = 256;
ConstraintLayout.LayoutParams lp =
new ConstraintLayout.LayoutParams(/*ConstraintLayout.LayoutParams.WRAP_CONTENT,*/ dimensionInPixel,
/*ConstraintLayout.LayoutParams.WRAP_CONTENT*/ dimensionInPixel);
//weather
for(int i=0; i<flightPlanWeather.weather.size(); i++ ){
ConstraintSet constraintSet = new ConstraintSet();
holder.mConstraintSetList.add(constraintSet);
ImageView imageView = new ImageView(mContext);
imageView.setId(View.generateViewId());
imageView.setImageResource(flightPlanWeather.weather.get( i ));
imageView.setLayoutParams(lp);
imageView.requestLayout();
holder.weather.add(imageView);
holder.mConstraintLayout.addView( imageView/*, lp */);
//}
constraintSet.clone(holder.mConstraintLayout);
float biasedValue = (1f/ (flightPlanWeather.weather.size()+1f)) * (i+1f);
Log.d(TAG, Float.toString( biasedValue ) +"i:"+ Integer.toString( i )+"size:"+ flightPlanWeather.weather.size());
constraintSet.setHorizontalBias(imageView.getId(), biasedValue);
constraintSet.connect(imageView.getId(), ConstraintSet.START, holder.mConstraintLayout.getId(), ConstraintSet.START, 0);
constraintSet.connect(imageView.getId(), ConstraintSet.END, holder.mConstraintLayout.getId(), ConstraintSet.END, 0);
constraintSet.connect(imageView.getId(), ConstraintSet.TOP, holder.mConstraintLayout.getId(), ConstraintSet.TOP, 0);
constraintSet.connect(imageView.getId(), ConstraintSet.BOTTOM, holder.mConstraintLayout.getId(), ConstraintSet.BOTTOM, 0);
constraintSet.applyTo(holder.mConstraintLayout);
holder.mConstraintLayout.requestLayout();
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return dataSet == null ? 0 : dataSet.size();
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
// Static inner class to initialize the views of rows
static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView from_label;
TextView to_label;
ImageView from_img;
ImageView to_img;
ImageView line;
ConstraintLayout mConstraintLayout;
List<ConstraintSet> mConstraintSetList = new ArrayList<>( );
List<ImageView> weather = new ArrayList<>( );
public MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mConstraintLayout = (ConstraintLayout) itemView.findViewById(R.id.mainConstraintLayout);
from_label = (TextView) itemView.findViewById(R.id.from_label);
to_label = (TextView) itemView.findViewById(R.id.to_label);
from_img = (ImageView) itemView.findViewById(R.id.from_img);
to_img = (ImageView) itemView.findViewById(R.id.to_img);
line = (ImageView) itemView.findViewById(R.id.line);
}
public void bind(Object object){
}
@Override
public void onClick(View view) {
Log.d("onclick", "onClick " + getLayoutPosition() + " " /*+ /*item.getText()*/);
}
}
}
问题是天气的水平偏差不能正常工作 截图
视图应该是这样的: screenshot
解决方案
问题是您正在为每个视图重用布局参数。由于布局参数承载布局信息,因此您创建的每个新ImageView并为其设置布局信息都会清除之前的。
为每个ImageView创建一组新的布局参数,它应该都可以工作。将以下内容移动到您的循环中:
ConstraintLayout.LayoutParams lp =
new ConstraintLayout.LayoutParams(/*ConstraintLayout.LayoutParams.WRAP_CONTENT,*/ dimensionInPixel,
/*ConstraintLayout.LayoutParams.WRAP_CONTENT*/ dimensionInPixel);
推荐阅读
- html - 为容器添加填充后,为什么我的按钮不起作用?
- c++ - 如何在不指定模板参数的情况下将 lambda 与模板参数匹配
- python - 在 Matplotlib 中更改 X 轴日期时间间隔
- python-3.x - 如何在python中将全名拆分为名字和姓氏?
- html - 如何使用 css 网格在第一行居中 1 列并将其他 3 列放在第二行?
- sql-server - SQL Server 中不会忽略重复项
- regex - 如何匹配彼此相邻的括号?
- api - 如何向 api 发送多个查询参数?
- javascript - Firebase功能分离线程?
- javascript - 如何使用 dom 选择器作为对象中的值迭代对象,然后使用它们来设置值?