Как использовать сеттеры для пользовательского представления в RecyclerView?

1

У меня есть пользовательское представление, которое имеет метод setHeadingString() для динамического задания заголовка. Я добавил несколько таких представлений в свой RecyclerView, но когда я хочу использовать для них setHeadingString(), заголовок в приложении не отображается.

Чтобы проверить, действительно ли работает метод setHeadingString(), я просто добавил новое представление в свой макет (как с помощью XML, так и кода) и использовал этот метод для него. Это сработало.
Мой пользовательский вид называется AccordionView (и AccordionItem - другой вид, который я использую, но не обращаю на это внимания).

Вот мой адаптер:

public class AllWorksAdapter extends RecyclerView.Adapter<AllWorksAdapter.ViewHolder> {

    private List<AccordionView> items;
    RecyclerView.RecycledViewPool viewPool;
    Context mContext;

    public AllWorksAdapter(List<AccordionView> dataset, Context context) {
        items = dataset;
        viewPool = new RecyclerView.RecycledViewPool();
        mContext = context;
    }

    public AllWorksAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View accordion = inflater.inflate(R.layout.item_accordion, parent, false);
        ViewHolder viewHolder = new ViewHolder(accordion);
        viewHolder.recyclerView.setRecycledViewPool(viewPool);



        return viewHolder;
    }

    @Override
    public void onBindViewHolder(AllWorksAdapter.ViewHolder viewHolder, int position) {
        AccordionView accordion = items.get(position);
        AccordionView accordionView = viewHolder.accordionView;
        RecyclerView recyclerView = viewHolder.recyclerView;
    }

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

    class ViewHolder extends RecyclerView.ViewHolder {
        AccordionView accordionView;
        RecyclerView recyclerView;
        TextView heading;

        ViewHolder(final View itemView) {
            super(itemView);

            accordionView = itemView.findViewById(R.id.accordionView);
            recyclerView = (RecyclerView) itemView.findViewById(R.id.recyclerView);
            heading = accordionView.findViewById(R.id.heading);
        }

    }
    public AccordionView getItem(int position) {
        return items.get(position);
    }
}

item_accordion.xml:

<com.app.myapp.views.AccordionView.AccordionView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/accordionView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="1dp"
    app:bodyBackgroundColor="@color/colorPrimaryDark"
    app:headingBackground="@drawable/accordion_heading"
    app:headingTextSize="7sp"
    app:isAnimated="true"
    app:isPartitioned="false">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="8dp">

    </android.support.v7.widget.RecyclerView>



    <com.app.myapp.views.AccordionItem
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="8dp"
        app:title="Title">

    </com.app.myapp.views.AccordionItem>

</com.app.myapp.views.AccordionView.AccordionView>

Вот как я добавляю его в свой фрагмент для теста:

private RecyclerView recyclerView;
ArrayList<AccordionView> items;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_all_works, container, false);

        recyclerView = view.findViewById(R.id.container);
        items = new ArrayList<>();
//Tried using different contexts
        AccordionView a1 = new AccordionView(getActivity());
        AccordionView a2 = new AccordionView(getActivity());
        AccordionView a3 = new AccordionView(getContext());
        AccordionView a4 = new AccordionView(getContext());
        a1.setHeadingString("Heading 1");
        a2.setHeadingString("Heading 2");
        a3.setHeadingString("Heading 3");
        a4.setHeadingString("Heading 4");


        try {
            items.add(a1);
            items.add(a2);
            items.add(a3);
            items.add(a4);
        } catch (Exception e) {
            e.printStackTrace();
        }

        AllWorksAdapter adapter = new AllWorksAdapter(items, getActivity());
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        return view;
    }

Я ожидаю, что мои представления в RecyclerView будут изменены при вызове setHeadingString(). Что я сделал не так?

Спасибо.


Обновить
Класс AccordionView по запросу:
public class AccordionView extends RelativeLayout {
    View[] children;

    Boolean isExpanded = false;

    Boolean isAnimated = false;

    Boolean isPartitioned = false;

    String headingString;

    View partition;

    TextView heading;

    ImageView icon;

    RelativeLayout paragraph;

    int headingTextSize;

    ImageView dropdownImage;

    ImageView dropupImage;

    private LayoutInflater inflater;

    ConstraintLayout headingLayout;

    int paragraphTopMargin;

    int paragraphBottomMargin;

    // int paragraphHeight;

    int headingBackgroundColor = Color.WHITE;

    int paragraphBackgroundColor = Color.WHITE;

    Drawable headingBackground;

    Drawable paragraphBackground;

    AccordionOnExpansionCollapseListener listener;

    Context mContext;


    public AccordionView(Context context) {
        super(context);
        mContext = context;
        prepareLayoutWithoutChildren(context);
    }

    public AccordionView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        handleAttributeSet(context, attrs);
    }

    public AccordionView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        handleAttributeSet(context, attrs);
    }

    private void handleAttributeSet(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AccordionView);

        isAnimated = a.getBoolean(R.styleable.AccordionView_isAnimated, false);
        isPartitioned = a.getBoolean(R.styleable.AccordionView_isPartitioned, false);
        headingString = a.getString(R.styleable.AccordionView_heading);
        isExpanded = a.getBoolean(R.styleable.AccordionView_isExpanded, false);
        headingTextSize = a.getDimensionPixelSize(R.styleable.AccordionView_headingTextSize, 20);
        headingBackgroundColor = a.getColor(R.styleable.AccordionView_headingBackgroundColor,Color.WHITE);
        paragraphBackgroundColor = a.getColor(R.styleable.AccordionView_bodyBackgroundColor,Color.WHITE);

        headingBackground = a.getDrawable(R.styleable.AccordionView_headingBackground);
        paragraphBackground = a.getDrawable(R.styleable.AccordionView_bodyBackground);
    }

    private void initializeViewWithoutChildren(Context context) {
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        LinearLayout accordionLayout = (LinearLayout) inflater.inflate(R.layout.accordion, null);
        partition = accordionLayout.findViewById(R.id.partition);
        heading = (TextView) accordionLayout.findViewById(R.id.heading);
        paragraph = (RelativeLayout) accordionLayout.findViewById(R.id.paragraph_layout);
        dropdownImage = (ImageView) accordionLayout.findViewById(R.id.dropdown_image);
        dropupImage = (ImageView) accordionLayout.findViewById(R.id.dropup_image);
        headingLayout = accordionLayout.findViewById(R.id.heading_layout);
        icon = accordionLayout.findViewById(R.id.icon);
        paragraph.removeAllViews();
        removeAllViews();
        paragraphBottomMargin = ((LinearLayout.LayoutParams) paragraph.getLayoutParams()).bottomMargin;
        paragraphTopMargin = ((LinearLayout.LayoutParams) paragraph.getLayoutParams()).topMargin;
        addView(accordionLayout);

    }


    private void initializeViews(Context context) {

        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        LinearLayout accordionLayout = (LinearLayout) inflater.inflate(R.layout.accordion, null);
        partition = accordionLayout.findViewById(R.id.partition);
        heading = (TextView) accordionLayout.findViewById(R.id.heading);
        paragraph = (RelativeLayout) accordionLayout.findViewById(R.id.paragraph_layout);
        dropdownImage = (ImageView) accordionLayout.findViewById(R.id.dropdown_image);
        dropupImage = (ImageView) accordionLayout.findViewById(R.id.dropup_image);
        headingLayout = accordionLayout.findViewById(R.id.heading_layout);
        icon = accordionLayout.findViewById(R.id.icon);
        paragraph.removeAllViews();

        int i;
        children = new View[getChildCount()];
        for (i = 0; i < getChildCount(); i++) {
            children[i] = getChildAt(i);
        }
        removeAllViews();
        for (i = 0; i < children.length; i++) {
            paragraph.addView(children[i]);
        }


        paragraphBottomMargin = ((LinearLayout.LayoutParams) paragraph.getLayoutParams()).bottomMargin;
        paragraphTopMargin = ((LinearLayout.LayoutParams) paragraph.getLayoutParams()).topMargin;

        addView(accordionLayout);


    }

    private void prepareLayout(Context context) {
        initializeViews(context);
        partition.setVisibility(isPartitioned ? VISIBLE : INVISIBLE);
        heading.setText(headingString);
        heading.setTextSize(headingTextSize);

        //Set the background on the heading...if the background drawable has been set by the user, use that. Else, set the background color
        if(!WidgetHelper.isNullOrBlank(headingBackground) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            headingLayout.setBackground(headingBackground);
        else
            headingLayout.setBackgroundColor(headingBackgroundColor);

        //Set the background on the paragraph...if the background drawable has been set by the user, use that. Else, set the background color
        if(!WidgetHelper.isNullOrBlank(paragraphBackground) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            paragraph.setBackground(paragraphBackground);
        else
            paragraph.setBackgroundColor(paragraphBackgroundColor);

        paragraph.setVisibility(VISIBLE);
        //paragraph.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);
        if (isAnimated) {
            headingLayout.setLayoutTransition(new LayoutTransition());
        } else {
            headingLayout.setLayoutTransition(null);

        }

        if (isExpanded)
            expand();
        else
            collapse();

        setOnClickListenerOnHeading();
        setOnLongClickListenerOnHeading();

    }

    private void prepareLayoutWithoutChildren(Context context) {
        initializeViewWithoutChildren(context);
        partition.setVisibility(isPartitioned ? VISIBLE : INVISIBLE);
        heading.setText(headingString);
        paragraph.setVisibility(VISIBLE);
        //paragraph.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);
        if (isAnimated) {
            headingLayout.setLayoutTransition(new LayoutTransition());
        } else {
            headingLayout.setLayoutTransition(null);

        }

        if (isExpanded)
            expand();
        else
            collapse();

        setOnClickListenerOnHeading();
        setOnLongClickListenerOnHeading();

    }

    protected void onFinishInflate() {
        prepareLayout(getContext());
        super.onFinishInflate();

    }

    private void expand() {
        if (isAnimated) {

            AccordionTransitionAnimation expandAnimation = new AccordionTransitionAnimation(paragraph, 300, AccordionTransitionAnimation.EXPAND);
            expandAnimation.setHeight(WidgetHelper.getFullHeight(paragraph));
            expandAnimation.setEndBottomMargin(paragraphBottomMargin);
            expandAnimation.setEndTopMargin(paragraphTopMargin);
            paragraph.startAnimation(expandAnimation);

        } else {
            paragraph.setVisibility(VISIBLE);
        }


        partition.setVisibility(isPartitioned ? VISIBLE : INVISIBLE);

        dropupImage.setVisibility(VISIBLE);
        dropdownImage.setVisibility(GONE);
        if(!WidgetHelper.isNullOrBlank(listener)) {
            listener.onExpanded(this);
        }


    }

    private void collapse() {

        if (isAnimated) {

            AccordionTransitionAnimation collapseAnimation = new AccordionTransitionAnimation(paragraph, 300, AccordionTransitionAnimation.COLLAPSE);
            paragraph.startAnimation(collapseAnimation);

        } else {
            paragraph.setVisibility(GONE);

        }

        partition.setVisibility(INVISIBLE);

        dropupImage.setVisibility(GONE);
        dropdownImage.setVisibility(VISIBLE);

        if(!WidgetHelper.isNullOrBlank(listener)) {
            listener.onCollapsed(this);
        }


    }

    private void setOnClickListenerOnHeading() {
        heading.setOnClickListener(toggleParagraphVisiblity);
        dropdownImage.setOnClickListener(toggleParagraphVisiblity);
        dropupImage.setOnClickListener(toggleParagraphVisiblity);
        icon.setOnClickListener(toggleParagraphVisiblity);
        headingLayout.setOnClickListener(toggleParagraphVisiblity);

    }

    OnClickListener toggleParagraphVisiblity = new OnClickListener() {
        @Override
        public void onClick(View view) {
            if (paragraph.getVisibility() == VISIBLE) {
                collapse();
            } else
                expand();
        }
    };

    private void setOnLongClickListenerOnHeading() {
        headingLayout.setOnLongClickListener(longClickListener);
        heading.setOnLongClickListener(longClickListener);
        dropdownImage.setOnLongClickListener(longClickListener);
        dropupImage.setOnLongClickListener(longClickListener);
        icon.setOnLongClickListener(longClickListener);
    }

    OnLongClickListener longClickListener = new OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            MainActivity mainActivity = (MainActivity) mContext;
            mainActivity.showActionsOnFileFragment(headingString, 2);
            return false;
        }
    };

    public void addViewToBody(View child) {
        paragraph.addView(child);
    }

    public void setHeadingString(String headingString) {
        this.headingString = headingString;
        heading.setText(headingString);
    }

    public Boolean getAnimated() {
        return isAnimated;
    }

    public void setAnimated(Boolean animated) {
        isAnimated = animated;
    }

    public void setOnExpandCollapseListener(AccordionOnExpansionCollapseListener listener) {
        this.listener = listener;
    }

    public RelativeLayout getBody() {
        return paragraph;
    }

    public RelativeLayout getParagraph() {
        return paragraph;
    }

    public Boolean getExpanded() {
        return isExpanded;
    }

    public void setExpanded(Boolean expanded) {
        isExpanded = expanded;
    }

    public Boolean getPartitioned() {
        return isPartitioned;
    }

    public String getHeadingString() { return headingString; }

    public void setPartitioned(Boolean partitioned) {
        isPartitioned = partitioned;
        partition.setVisibility(isPartitioned ? VISIBLE : INVISIBLE);
    }

    public void setHeadingBackGround(Drawable drawable) {

        if(WidgetHelper.isNullOrBlank(headingLayout))
            headingLayout = findViewById(R.id.heading_layout);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            headingLayout.setBackground(drawable);
        }
    }

    public void setHeadingBackGround(int resId) {
        Drawable drawable = getResources().getDrawable(resId);

        if(WidgetHelper.isNullOrBlank(headingLayout))
            headingLayout = findViewById(R.id.heading_layout);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            headingLayout.setBackground(drawable);
        }
    }

    public void setBodyBackGround(Drawable drawable) {

        if(WidgetHelper.isNullOrBlank(paragraph))
            paragraph = (RelativeLayout) findViewById(R.id.paragraph_layout);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            paragraph.setBackground(drawable);
        }
    }

    public void setBodyBackGround(int resId) {
        Drawable drawable = getResources().getDrawable(resId);

        if(WidgetHelper.isNullOrBlank(paragraph))
            paragraph = (RelativeLayout) findViewById(R.id.paragraph_layout);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            paragraph.setBackground(drawable);
        }
    }

    public void setHeadingBackGroundColor(int color) {

        if(WidgetHelper.isNullOrBlank(headingLayout))
            headingLayout = findViewById(R.id.heading_layout);
        headingLayout.setBackgroundColor(color);

    }

    public void setBodyBackGroundColor(int color) {

        if(WidgetHelper.isNullOrBlank(paragraph))
            paragraph = (RelativeLayout) findViewById(R.id.paragraph_layout);
        paragraph.setBackgroundColor(color);

    }

}
Теги:
recycler-adapter
android-recyclerview
android-view

1 ответ

0

В вашем методе Adapter onBindViewHolder вам нужно заполнить свой пользовательский вид, и там вам нужно вызвать метод "setHeadingString". подобно

   @Override
public void onBindViewHolder(AllWorksAdapter.ViewHolder viewHolder, int position) {
    AccordionView accordion = new AccordionView()// initialization
    accordion.setHeadingString(items.get(position).getHeading());
}

И лучше использовать пользовательский класс Model в качестве списка элементов, а не пользовательский тип представления. подобно

 private List<YourModelClass> items;

И тогда, где вам нужно изменить заголовок, просто измените его в списке элементов и вызовите

 adapter.notifyDataSetChanged();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню