Динамическое добавление пользовательского представления в recyclerview

Мне нужно создать новое пользовательское представление для каждого элемента, добавленного в представление ресайклера.

@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 для вызова отрисовки пользовательского представления. Основное требование - это каждый раз, когда новый элемент добавляется в представление ресайклера, мне нужно создать настраиваемое представление для этого элемента и выполнить настройку элемента.

Что именно вы имеете в виду, говоря «не может идентифицировать просмотр анимации»?

Mike M. 13.03.2018 23:59

Я не могу добавить customview в элемент списка. Я хочу нарисовать собственный холст в каждом элементе списка. AnimationView - это настраиваемый вид, расширяющий View.

varun bhargava 14.03.2018 00:03

Все еще не ясно. Что означает точно "не может идентифицировать представление анимации"? Вы получаете ошибку компиляции? Типа «Не удается решить ...»? Или он вылетает при запуске? Если да, то в чем же исключение?

Mike M. 14.03.2018 00:07

Это ошибка компиляции, в которой говорится, что переменная animationView не может быть найдена.

varun bhargava 14.03.2018 01:44

Который из? R.layout.animationView, R.id.animationView или другой? R.id выглядит правильным, так вы уверены, что имя файла макета XML - animationView.xml?

Mike M. 14.03.2018 01:59

AnimationView - это мой собственный класс, расширяющий View. И я пытаюсь использовать это представление в моем списке.

varun bhargava 14.03.2018 02:17

Да, я все это понимаю. Я задаю здесь очень конкретные вопросы. Мне нужны конкретные ответы, чтобы помочь. Вы заявили, что «говорится, что переменная animationView не может быть найдена». Какое именно появление animationView в опубликованном коде вызывает ошибку? Вы используете animationView как минимум тремя разными способами: ресурс R.layout, ресурс R.id и переменную Java. Какой именно показывает ошибку?

Mike M. 14.03.2018 02:22

R.layout.animationView вызывает проблему

varun bhargava 14.03.2018 02:25

Хорошо, а каково имя XML-файла, содержащего элемент <com.example.rckja.cs639springhw4.CircleAnimationView ..., который вы показываете в последнем блоке вашего кода? Последней частью R.layout. должно быть имя этого файла (без расширения .xml).

Mike M. 14.03.2018 02:27
0
9
2 750
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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.
    }
}

Надеюсь это поможет. Удачи и удачного кодирования.

Только одно сомнение, почему вы использовали два держателя обзора. Спасибо за вашу помощь и время.

varun bhargava 14.03.2018 01:01

И в моем требовании я должен использовать CustomView, который расширяет View, и мне нужно нарисовать холст внутри моего представления.

varun bhargava 14.03.2018 01:38

@varunbhargava Я использовал 2 держателя представлений и держатель основного представления, чтобы продемонстрировать использование разных держателей представлений с разными макетами. Технически у вас может быть даже несколько держателей представлений, которые используют разные типы данных. По вашему требованию вы в основном создаете представление, добавляя его к зрителю. Вы можете рисовать на нем при создании представления, если вам не нужны данные для рисования. Или вы можете инициировать перерисовку представления, используя данные, переданные при вызове метода bind (). Я бы направил вас к документации разработчиков Android для получения подробной информации по этому поводу. developer.android.com/training/custom-views/custom-drawing.h tml.

doubleA 14.03.2018 18:45

В моем представлении ресайклера я пытаюсь создать новое настраиваемое представление и каждый раз, когда хочу сделать его недействительным.

varun bhargava 18.03.2018 04:35

Я обновил ваш вопрос. Не могли бы вы разобраться в проблеме?

varun bhargava 18.03.2018 04:44

Другие вопросы по теме