首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >RecyclerView粘性标题

RecyclerView粘性标题
EN

Stack Overflow用户
提问于 2019-04-10 04:33:00
回答 1查看 0关注 0票数 0

我一直在Android中的RecyclerView中添加标题,我想要的结果是:

当前警报和历史记录有两个标题
当前警报和历史记录有两个标题

有两个标题CurrentAlert和History。我一直在向RecyclerView添加标题,这就是我现在所拥有的:

在此输入图像描述
在此输入图像描述

如何在Current Alert和StateHistory中对项目进行分组,而不在列表中的每个元素中包含多个标题?与第一个屏幕类似。这是我的代码:

代码语言:javascript
复制
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.example.evaluationtask.Model.StateModel;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    RecyclerView.LayoutManager layoutManager;
    ViewAdapter viewAdapter;
    List<StateModel> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        list = new ArrayList<>();
        loadJSONFromAsset();

        viewAdapter = new ViewAdapter(list);

        System.out.println("List Items : " + list);
        recyclerView.setAdapter(viewAdapter);

        RecyclerSectionItemDecoration sectionItemDecoration = new RecyclerSectionItemDecoration(getResources()
                .getDimensionPixelSize(R.dimen.header),
                true,
                getSectionCallback(list));
        recyclerView.addItemDecoration(sectionItemDecoration);
        viewAdapter.notifyDataSetChanged();


    }

    public void loadJSONFromAsset() {
        String json;

        try {

            InputStream inputStream = getAssets().open("StateAlert.json");
            int size = inputStream.available();
            byte[] buffer = new byte[size];
            inputStream.read(buffer);
            inputStream.close();
            json = new String(buffer, StandardCharsets.UTF_8);
            JSONArray jsonElements = new JSONArray(json);

            for (int i = 0; i < jsonElements.length(); i++) {

                JSONObject jsonObject = jsonElements.getJSONObject(i);
                StateModel stateModel = new StateModel();
                stateModel.setId(jsonObject.optInt("id", 0));
                stateModel.setCreated(jsonObject.optString("Created", "N/A"));
                stateModel.setDescription(jsonObject.optString("Description", "N/A"));
                stateModel.setHistoryCount(jsonObject.optInt("HistoryCount", 0));
                stateModel.setStatus(jsonObject.optString("Status", "N/A"));
                stateModel.setType(jsonObject.optString("Type", "N/A"));
                list.add(stateModel);

            }

        } catch (IOException e) {

            e.printStackTrace();
        } catch (JSONException e) {

            e.printStackTrace();
        }
    }

    private RecyclerSectionItemDecoration.SectionCallback getSectionCallback(final List<StateModel> stateModels) {
        return new RecyclerSectionItemDecoration.SectionCallback() {
            @Override
            public boolean isSection(int position) {
                return true;
            }

            @Override
            public CharSequence getSectionHeader(int position) {
                return stateModels.get(position)
                        .getType();
            }
        };
    }
}

RecyclerSectionItemDecoration类是:

代码语言:javascript
复制
import android.graphics.Canvas;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

class RecyclerSectionItemDecoration extends RecyclerView.ItemDecoration {

    private final int headerOffset;
    private final boolean sticky;
    private final SectionCallback sectionCallback;

    private View headerView;
    private TextView header;

    public RecyclerSectionItemDecoration(int headerHeight, boolean sticky, @NonNull SectionCallback sectionCallback) {
        headerOffset = headerHeight;
        this.sticky = sticky;
        this.sectionCallback = sectionCallback;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        int pos = parent.getChildAdapterPosition(view);
        if (sectionCallback.isSection(pos)) {
            outRect.top = headerOffset;
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);

        if (headerView == null) {
            headerView = inflateHeaderView(parent);
            header = headerView.findViewById(R.id.tv_header);
            fixLayoutSize(headerView, parent);
        }

        CharSequence previousHeader = "";
        for (int i = 0; i < parent.getChildCount(); i++) {
            View child = parent.getChildAt(i);
            final int position = parent.getChildAdapterPosition(child);

            CharSequence title = sectionCallback.getSectionHeader(position);
            header.setText(title);
            if (!previousHeader.equals(title) || sectionCallback.isSection(position)) {
                drawHeader(c, child, headerView);
                previousHeader = title;
            }
        }
    }

    private void drawHeader(Canvas c, View child, View headerView) {
        c.save();
        if (sticky) {
            c.translate(0, Math.max(0, child.getTop() - headerView.getHeight()));
        } else {
            c.translate(0, child.getTop() - headerView.getHeight());
        }
        headerView.draw(c);
        c.restore();
    }

    private View inflateHeaderView(RecyclerView parent) {
        return LayoutInflater.from(parent.getContext())
                .inflate(R.layout.view_header, parent, false);
    }

    private void fixLayoutSize(View view, ViewGroup parent) {
        int widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(),
                View.MeasureSpec.EXACTLY);
        int heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(),
                View.MeasureSpec.UNSPECIFIED);

        int childWidth = ViewGroup.getChildMeasureSpec(widthSpec,
                parent.getPaddingLeft() + parent.getPaddingRight(),
                view.getLayoutParams().width);
        int childHeight = ViewGroup.getChildMeasureSpec(heightSpec,
                parent.getPaddingTop() + parent.getPaddingBottom(),
                view.getLayoutParams().height);

        view.measure(childWidth, childHeight);

        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    }

    public interface SectionCallback {

        boolean isSection(int position);

        CharSequence getSectionHeader(int position);
    }


}

这是适配器:

代码语言:javascript
复制
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.example.evaluationtask.Model.StateModel;

import java.util.List;

public class ViewAdapter extends RecyclerView.Adapter<ViewAdapter.ItemViewHolder> {

    List<StateModel> dataSet;

    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_list_view, viewGroup, false);
        return new ItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ItemViewHolder itemViewHolder, int i) {
        itemViewHolder.button.setText(dataSet.get(i).getStatus());
        itemViewHolder.shoreTitle.setText(dataSet.get(i).getDescription());
        itemViewHolder.createdAt.setText(dataSet.get(i).getCreated());

    }

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

    public static class ItemViewHolder extends RecyclerView.ViewHolder {
        public TextView shoreTitle;
        public TextView createdAt;
        public Button button;

        public ItemViewHolder(@NonNull View itemView) {
            super(itemView);
            this.createdAt = itemView.findViewById(R.id.createdAt);
            this.shoreTitle = itemView.findViewById(R.id.shore_text);
            this.button = itemView.findViewById(R.id.btn_card);
        }
    }

    public ViewAdapter(List<StateModel> dataSet) {
        this.dataSet = dataSet;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2019-04-10 13:40:45

实际上,你误用了RecyclerView.ItemDecoration,它主要用作Divider(而不是Header),

为什么不尝试如下:

代码语言:javascript
复制
<ViewGroup>(such as ConstraintLayout)
<View>(Alert Header)
<RecyclerView>(Alert RecyclerView)

<View>(History Header)
<RecyclerView>(History RecyclerView)
</ViewGroup>

或者有一个带有两个List的RecyclerView,并根据列表放置相应的Header,可选择使用Flag只添加一次

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100006562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档