【问题标题】:Add custom view dynamically to a recyclerview [closed]将自定义视图动态添加到 recyclerview [关闭]
【发布时间】:2018-03-13 22:15:54
【问题描述】:

我必须为添加到回收站视图中的每个项目创建一个新的自定义视图。

@Override
public ListViewAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
    BaseViewHolder viewHolder =new BaseViewHolder(view);
    return viewHolder;
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
    if(holder instanceof BaseViewHolder){
    circleAnimationViewClass =new CircleAnimationView(mContext);

    circleAnimationViewClass.addRadius(circleList.get(position).getRadius());
    circleAnimationViewClass.addSpeed(circleList.get(position).getSpeed());
    circleAnimationViewClass.addColor(circleList.get(position).getColor());
    if(getItemViewType(position) >-1){
        circleAnimationViewClass.onStart();
        holder.bindCircle(circleList.get(position));

    }
    }

}
public class BaseViewHolder extends RecyclerView.ViewHolder {

    protected Context mActivityContext;
    View circleAnimationView;
    TextView radiusTextView;
    TextView speedTextView;
    public BaseViewHolder(View itemView) {
        super(itemView);
        this.circleAnimationView = (CircleAnimationView ) itemView.findViewById(R.id.animationView);
        this.radiusTextView = (TextView)itemView.findViewById(R.id.radiusText);
        this.speedTextView=(TextView)itemView.findViewById(R.id.speedText);
        mActivityContext =itemView.getContext();
    }
    public void bindCircle(CircleProperties objCircle){
        circleAnimationViewClass.drawCanvas((CircleProperties)objCircle);
        circleAnimationViewClass.invalidate();
    }
}

这是我的圆形动画课

 public void addRadius(int radius){
        circleRadius =radius;
    }
    public void addSpeed(int speed){
        circleSpeed=speed;
    }
    public void addColor(int color){
        circleColor= color;
    }
 public CircleAnimationView(Context context, AttributeSet attributes) 
{
        super(context, attributes);
        TypedArray typedArray = context.obtainStyledAttributes(attributes, R.styleable.CircleAnimationView);
        circleRadius = typedArray.getColor(R.styleable.CircleAnimationView_radius, 20);
        circleSpeed = typedArray.getColor(R.styleable.CircleAnimationView_speed, 100);
        circleColor =typedArray.getColor(R.styleable.CircleAnimationView_circleColor, Color.BLACK);
        typedArray.recycle();
    }


    @Override
    public void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
            Paint paint = new Paint();
            paint.setStrokeWidth(5);
            paint.setColor(circleColor);
            if (i == 0) {
                startXPos = dpToPx(circleRadius);
                i = dpToPx(circleRadius);
                canvas.drawCircle(startXPos, dpToPx(40), dpToPx(circleRadius), paint);
                //canvas.drawCircle(dpToPx(200), dpToPx(200), dpToPx(30), paint);
            } else {
                startXPos =   startXPos >= (canvas.getWidth() - dpToPx(circleRadius)) ? dpToPx(circleRadius) : startXPos + dpToPx(circleSpeed / 16);

                canvas.drawCircle(startXPos, dpToPx(40), dpToPx(circleRadius), paint);

            }
            i++;
    }

问题是当我没有在 onDraw 中获得半径和速度的值时。我正在使用 invalidate 来调用自定义视图的 ondraw。主要要求是每次将新项目添加到回收站视图时,我都需要为该项目创建自定义视图并对项目进行自定义操作。

【问题讨论】:

  • “无法识别动画视图”到底是什么意思?
  • 我无法将自定义视图添加到列表项。我想在每个列表项中进行自定义画布绘制。 AnimationView 是扩展 View 的自定义视图。
  • 还是不清楚。 “无法识别动画视图”究竟是什么意思?您是否收到编译错误?比如“无法解决……”?还是运行时崩溃?如果是这样,例外是什么?
  • 这是一个编译错误,提示找不到 animationView 变量。
  • 哪一个? R.layout.animationViewR.id.animationView 还是其他? R.id 看起来是正确的,所以您确定 XML 布局文件的名称是 animationView.xml

标签: android listview custom-view


【解决方案1】:

正确使用 Recycler View 或至少使用视图持有者模式。还有 RecyclerView.Adapter。

public class ListViewAdapter extends RecyclerView.Adapter<BaseViewHolder> {

private List<CircleProperties> properties;

ListViewAdapter(Activity context, List<CircleProperties> circleObjectList){
    mContext = context;
    circleList =circleObjectList;
}

@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if(viewType.equals(A_VIEW_TYPE) {
        return new CircleAViewHolder(mActivityContext, mInflater.inflate(CircleViewHolder.CIRCLE_A_VIEW_ID, parent, false));
    } else if(viewType.equals(B_VIEW_TYPE) {
        new CircleAViewHolder(mActivityContext, mInflater.inflate(CircleViewHolder.CIRCLE_B_VIEW_ID, parent, false));
    }       
}

@Override
public int getItemViewType(int position) {
    return properties.get(position).getType();
}

@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
    holder.bind(properties.get(position));
}

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

然后像这样创建视图持有者...

public class BaseViewHolder extends RecyclerView.ViewHolder {

protected Context mActivityContext;
protected int mPosition;

public BaseViewHolder(View itemView) {
    super(itemView);
}

public BaseViewHolder(Context context, View itemView) {
    super(itemView);
    mActivityContext = context;

}

public void bind(Object data){
}
}

以及像这样的视图持有者的子类...

private class CircleAViewHolder extends BaseViewHolder{

    CircleAnimationView circleAnimationView;
    TextView radiusTextView;
    TextView speedTextView;

    ViewHolder(Context context, View itemView) {
        this.circleAnimationView = (CircleAnimationView ) itemView.findViewById(R.id.circle_animation_view);
        this.radiusTextView = (TextView)itemView.findViewById(R.id.radius_view);
        this.speedTextView=(TextView)itemView.findViewById(R.id.speed_text_view);
    }

    public void bind(Object data){
        CircleProperties circleProp = (CircleProperties) data;
        radiusTextView.setText(circleProp.getRadius());
        speedTextView.setText(circleProp.getSpeed());
        animaitonView.drawCanvas(data);
        //TODO: Any other view setup using data.
    }
}

还有第二个视图持有者,例如...

private class CircleBViewHolder extends BaseViewHolder{

    CircleAnimationView animationView;
    TextView diameterTextView;
    TextView velocityTextView;

    ViewHolder(Context context, View itemView) {
        this.animationView = (CircleAnimationView) itemView.findViewById(R.id.animation_view);
        this.diameterTextView =(TextView)itemView.findViewById(R.id.diameter_view);
        this.velocityTextView=(TextView)itemView.findViewById(R.id.velocity_text_view);
    }

    public void bind(Object data){
        CircleProperties circleProp = (CircleProperties) data;
        diameterTextView.setText(circleProp.getDiameter());
        velocityTextView.setText(circleProp.getVelocity());
        animaitonView.drawCanvas(data);
        //TODO: Any other view setup using data.
    }
}

【讨论】:

  • 只有一个疑问,为什么您使用了两个视图支架。感谢您的帮助和时间。
  • 在我的要求中,我必须使用扩展 View 的 CustomView,并且我需要在我的视图中绘制画布。
  • @varunbhargava 我使用了 2 个视图支架和一个基本视图支架来演示如何使用具有不同布局的不同视图支架。从技术上讲,您甚至可以拥有多个使用不同数据类型的视图持有者。根据您的要求,您基本上创建了一个视图,将其添加到 viewholder。如果您不需要绘制数据,则可以在创建视图时在其上绘制。或者,您可以使用在 bind() 方法调用中传递的数据触发视图重绘。我会指导您查看 android dev 文档以获取有关此内容的详细信息。 developer.android.com/training/custom-views/custom-drawing.html
  • 在我的回收站视图中,我正在尝试创建一个新的自定义视图,并且每次我想使其失效。
  • 我已经更新了你的问题,你能看看这个问题吗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多