芯片组中的多排芯片
Multiple row of chips in chipgroup
我正在从我的 API 中获取一个列表,例如德国、英国、法国、意大利等国家/地区的 25 个标签...
我想要 2 行,每行 10 chips
,如果我下次获取 30 个标签,我想要 3 行,每行 10 chips
等...
到目前为止,我还没有发现任何允许我这样做的东西。我快速浏览了 Flexbox-Layout
但它似乎不符合我的需要,我目前有下面的代码,但我正在考虑用 Recyclerview
[=16= 来做这样的逻辑]
片段
viewModel.videoSelected.observe(viewLifecycleOwner, object : Observer<VideoPage> {
override fun onChanged(videoPage: VideoPage?) {
videoPage?.tags ?: return
val chipGroup = binding.chipGroup
val chipGroupInflater = LayoutInflater.from(chipGroup.context)
val children = videoPage.tags.map { tagName ->
val chip = chipGroupInflater.inflate(R.layout.chip_video_tag, chipGroup, false) as Chip
chip.text = tagName
chip.tag = tagName
chip.setOnClickListener {
Toast.makeText(context, tagName, Toast.LENGTH_SHORT).show()
}
chip
}
for (chip in children) {
chipGroup.addView(chip)
}
}
})
结果是一行中有 25 个筹码。我怎样才能让它分成多行?
如评论所述,您可以在筹码 11、21 等
上使用带有 layout_wrapBefore 标志的 Flexbox LayoutManager
或者如果您重新格式化数据,也可以使用标准的回收视图。
要使用标准的 recyclerview 来做到这一点,您需要将数据排列在二维数据结构中,这可以是 Arraylists 的 ArrayList 或 Arrays 或一组 POJO 类
在外部 Arraylist 中是行,在内部 Arraylist 中您将在行中显示项目。
所以 RecyclerView 项目只是一个水平线性布局来生成行,您可以从内部 ArrayList 添加您的筹码
使用生成的 2D 结构的示例
主要活动
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RAdapter adapter;
private ArrayList<ArrayList<String>> rowsArrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
rowsArrayList = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
ArrayList<String> row = new ArrayList<>();
for (int j = 1; j <= 10; j++) {
row.add(String.valueOf(j));
}
rowsArrayList.add(row);
}
adapter = new RAdapter(this, rowsArrayList);
recyclerView.setAdapter(adapter);
}
}
RAdapter
public class RAdapter extends RecyclerView.Adapter<RAdapter.RHolder>{
class RHolder extends RecyclerView.ViewHolder {
private LinearLayout line;
public RHolder(View itemView) {
super(itemView);
line = itemView.findViewById(R.id.line);
}
}
private Context context;
private ArrayList<ArrayList<String>> rowsArrayList;
public RAdapter(Context context, ArrayList<ArrayList<String>> rowsArrayList) {
this.context = context;
this.rowsArrayList = rowsArrayList;
}
@Override
public RHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new RHolder(view);
}
@Override
public void onBindViewHolder(RHolder holder, int position) {
// Because we might be recycling the LinearLayout that might have had chips added to it already
holder.line.removeAllViews();
ArrayList<String> row = rowsArrayList.get(position);
for (String text: row) {
Chip chip = new Chip(context);
chip.setText(text);
holder.line.addView(chip);
}
}
@Override
public int getItemCount() {
return rowsArrayList.size();
}
}
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/line">
</LinearLayout>
这产生了
更新:
多一点数学就可以做到,而无需重新排列数据
显示 25 个项目以涵盖未满行的用例
主要活动
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RAdapter adapter;
private ArrayList<String> itemsArrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
itemsArrayList = new ArrayList<>();
for (int i = 1; i <= 25; i++) {
itemsArrayList.add(String.valueOf(i));
}
adapter = new RAdapter(this, itemsArrayList);
recyclerView.setAdapter(adapter);
}
}
RAdapter
public class RAdapter extends RecyclerView.Adapter<RAdapter.RHolder>{
class RHolder extends RecyclerView.ViewHolder {
private LinearLayout line;
public RHolder(View itemView) {
super(itemView);
line = itemView.findViewById(R.id.line);
}
}
private Context context;
private ArrayList<String> itemsArrayList;
private int itemsPerRow = 10;
public RAdapter(Context context, ArrayList<String> itemsArrayList) {
this.context = context;
this.itemsArrayList = itemsArrayList;
}
@Override
public RHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new RHolder(view);
}
@Override
public void onBindViewHolder(RHolder holder, int position) {
// Because we might be recycling the LinearLayout that might have had chips added to it already
holder.line.removeAllViews();
int adjustedPosition = position + 1;
int rangeEnd = Math.min(itemsArrayList.size(), adjustedPosition * itemsPerRow);
int rangeStart = Math.max((position * itemsPerRow) + 1, rangeEnd - itemsPerRow);
for (int i = rangeStart; i <= rangeEnd; i++) {
int arrayPositionAdjusted = i - 1;
Chip chip = new Chip(context);
chip.setText(itemsArrayList.get(arrayPositionAdjusted));
holder.line.addView(chip);
}
}
@Override
public int getItemCount() {
return return (int) Math.ceil(itemsArrayList.size()/ (double) itemsPerRow);
}
}
生产
我还设法以一种更简单的方式做到了 BindingAdapter
:
<androidx.recyclerview.widget.RecyclerView
app:listVideoTagChip="@{viewModel.videoSelected.tags}"
android:id="@+id/rv_video_chips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
android:orientation="horizontal"
tools:listitem="@layout/chip_video_tag"/>
private const val TAG_PER_ROW = 10
@BindingAdapter("listVideoTagChip")
fun RecyclerView.bindRecyclerView(data: List<String>?) {
val adapter: VideoTagAdapter = this.adapter as VideoTagAdapter
(layoutManager as StaggeredGridLayoutManager).spanCount =
data?.size?.let {
ceil(it.toDouble().div(TAG_PER_ROW)).toInt()
} ?: 1
adapter.submitList(data)
}
我正在从我的 API 中获取一个列表,例如德国、英国、法国、意大利等国家/地区的 25 个标签...
我想要 2 行,每行 10 chips
,如果我下次获取 30 个标签,我想要 3 行,每行 10 chips
等...
到目前为止,我还没有发现任何允许我这样做的东西。我快速浏览了 Flexbox-Layout
但它似乎不符合我的需要,我目前有下面的代码,但我正在考虑用 Recyclerview
[=16= 来做这样的逻辑]
片段
viewModel.videoSelected.observe(viewLifecycleOwner, object : Observer<VideoPage> {
override fun onChanged(videoPage: VideoPage?) {
videoPage?.tags ?: return
val chipGroup = binding.chipGroup
val chipGroupInflater = LayoutInflater.from(chipGroup.context)
val children = videoPage.tags.map { tagName ->
val chip = chipGroupInflater.inflate(R.layout.chip_video_tag, chipGroup, false) as Chip
chip.text = tagName
chip.tag = tagName
chip.setOnClickListener {
Toast.makeText(context, tagName, Toast.LENGTH_SHORT).show()
}
chip
}
for (chip in children) {
chipGroup.addView(chip)
}
}
})
结果是一行中有 25 个筹码。我怎样才能让它分成多行?
如评论所述,您可以在筹码 11、21 等
上使用带有 layout_wrapBefore 标志的 Flexbox LayoutManager或者如果您重新格式化数据,也可以使用标准的回收视图。
要使用标准的 recyclerview 来做到这一点,您需要将数据排列在二维数据结构中,这可以是 Arraylists 的 ArrayList 或 Arrays 或一组 POJO 类
在外部 Arraylist 中是行,在内部 Arraylist 中您将在行中显示项目。
所以 RecyclerView 项目只是一个水平线性布局来生成行,您可以从内部 ArrayList 添加您的筹码
使用生成的 2D 结构的示例
主要活动
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RAdapter adapter;
private ArrayList<ArrayList<String>> rowsArrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
rowsArrayList = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
ArrayList<String> row = new ArrayList<>();
for (int j = 1; j <= 10; j++) {
row.add(String.valueOf(j));
}
rowsArrayList.add(row);
}
adapter = new RAdapter(this, rowsArrayList);
recyclerView.setAdapter(adapter);
}
}
RAdapter
public class RAdapter extends RecyclerView.Adapter<RAdapter.RHolder>{
class RHolder extends RecyclerView.ViewHolder {
private LinearLayout line;
public RHolder(View itemView) {
super(itemView);
line = itemView.findViewById(R.id.line);
}
}
private Context context;
private ArrayList<ArrayList<String>> rowsArrayList;
public RAdapter(Context context, ArrayList<ArrayList<String>> rowsArrayList) {
this.context = context;
this.rowsArrayList = rowsArrayList;
}
@Override
public RHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new RHolder(view);
}
@Override
public void onBindViewHolder(RHolder holder, int position) {
// Because we might be recycling the LinearLayout that might have had chips added to it already
holder.line.removeAllViews();
ArrayList<String> row = rowsArrayList.get(position);
for (String text: row) {
Chip chip = new Chip(context);
chip.setText(text);
holder.line.addView(chip);
}
}
@Override
public int getItemCount() {
return rowsArrayList.size();
}
}
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/line">
</LinearLayout>
这产生了
更新:
多一点数学就可以做到,而无需重新排列数据
显示 25 个项目以涵盖未满行的用例
主要活动
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RAdapter adapter;
private ArrayList<String> itemsArrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
itemsArrayList = new ArrayList<>();
for (int i = 1; i <= 25; i++) {
itemsArrayList.add(String.valueOf(i));
}
adapter = new RAdapter(this, itemsArrayList);
recyclerView.setAdapter(adapter);
}
}
RAdapter
public class RAdapter extends RecyclerView.Adapter<RAdapter.RHolder>{
class RHolder extends RecyclerView.ViewHolder {
private LinearLayout line;
public RHolder(View itemView) {
super(itemView);
line = itemView.findViewById(R.id.line);
}
}
private Context context;
private ArrayList<String> itemsArrayList;
private int itemsPerRow = 10;
public RAdapter(Context context, ArrayList<String> itemsArrayList) {
this.context = context;
this.itemsArrayList = itemsArrayList;
}
@Override
public RHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new RHolder(view);
}
@Override
public void onBindViewHolder(RHolder holder, int position) {
// Because we might be recycling the LinearLayout that might have had chips added to it already
holder.line.removeAllViews();
int adjustedPosition = position + 1;
int rangeEnd = Math.min(itemsArrayList.size(), adjustedPosition * itemsPerRow);
int rangeStart = Math.max((position * itemsPerRow) + 1, rangeEnd - itemsPerRow);
for (int i = rangeStart; i <= rangeEnd; i++) {
int arrayPositionAdjusted = i - 1;
Chip chip = new Chip(context);
chip.setText(itemsArrayList.get(arrayPositionAdjusted));
holder.line.addView(chip);
}
}
@Override
public int getItemCount() {
return return (int) Math.ceil(itemsArrayList.size()/ (double) itemsPerRow);
}
}
生产
我还设法以一种更简单的方式做到了 BindingAdapter
:
<androidx.recyclerview.widget.RecyclerView
app:listVideoTagChip="@{viewModel.videoSelected.tags}"
android:id="@+id/rv_video_chips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
android:orientation="horizontal"
tools:listitem="@layout/chip_video_tag"/>
private const val TAG_PER_ROW = 10
@BindingAdapter("listVideoTagChip")
fun RecyclerView.bindRecyclerView(data: List<String>?) {
val adapter: VideoTagAdapter = this.adapter as VideoTagAdapter
(layoutManager as StaggeredGridLayoutManager).spanCount =
data?.size?.let {
ceil(it.toDouble().div(TAG_PER_ROW)).toInt()
} ?: 1
adapter.submitList(data)
}