Android Netease cloud history search and hot Tags
Recently, we have developed a Netease cloud music player. There is a need to display search suggestions and historical search records
Project address: https://github.com/shellhub/NetEaseMusic

As can be seen from the rendering, if the label is too long to accommodate, it will wrap automatically. Although we can implement our own custom View, we don't need to build the wheel repeatedly in our short life. Here, we recommend Google's library flexbox-layout
Add dependency
implementation 'com.google.android:flexbox:1.1.0'
code implementation
First of all, we can use RecyclerView to implement this layout. Here we need to use the multiple layouts of RecyclerView, but for the sake of simplicity, we only need to look at the RecyclerView.
First, we initialize RecyclerView in your Activity or Fragment, then set the layout manager of RecyclerView, and then we can, simply, just one line of code
rvHots.setLayoutManager(new FlexboxLayoutManager(getContext()));
The complete code is as follows
public class HistoryFragment extends Fragment { private String TAG = TagUtils.getTag(this.getClass()); @BindView(R.id.iv_remove_history) ImageView ivRemoveHistory; @BindView(R.id.rvHots) RecyclerView rvHots; @BindView(R.id.rvHistory) RecyclerView rvHistory; HotSearchAdapter mHotSearchAdapter; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_search_hot, container, false); ButterKnife.bind(this, view); setup(); return view; } @Override public void onStart() { super.onStart(); if (!EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().register(this); } } private void setup() { rvHots.setAdapter(mHotSearchAdapter = new HotSearchAdapter()); rvHots.setLayoutManager(new FlexboxLayoutManager(getContext())); } @Subscribe(threadMode = ThreadMode.MAIN) public void onHotsReady(HotResponse hotResponse) { mHotSearchAdapter.setHots(hotResponse.getResult().getHots()); mHotSearchAdapter.notifyDataSetChanged(); } }
package shellhub.github.neteasemusic.adapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.blankj.utilcode.util.LogUtils; import org.greenrobot.eventbus.EventBus; import java.util.ArrayList; import java.util.List; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import butterknife.BindView; import butterknife.ButterKnife; import lombok.Data; import shellhub.github.neteasemusic.R; import shellhub.github.neteasemusic.model.entities.HistoryEvent; import shellhub.github.neteasemusic.util.TagUtils; @Data public class HistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private String TAG = TagUtils.getTag(this.getClass()); private List<String> histories = new ArrayList<>(); @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hot_item, parent, false); ButterKnife.bind(this, view); return new HistoryViewHolder(view); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof HistoryViewHolder) { ((HistoryViewHolder) holder).bind(position); } } @Override public int getItemCount() { LogUtils.d(TAG, histories.size()); return histories.size(); } public class HistoryViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.tv_hot) TextView tvHistory; public HistoryViewHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this, itemView); } public void bind(int position) { tvHistory.setText(histories.get(position)); itemView.setOnClickListener((view) -> { EventBus.getDefault().post(new HistoryEvent(histories.get(position))); }); } } }