导入依赖:implementation ‘com.android.support:recyclerview-v7:28.0.0’
main_activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/contents"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
item_channel_normal未选择
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingLeft="4dp"
android:paddingBottom="4dp"
android:paddingRight="4dp"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="频道管理"
android:gravity="center_horizontal"
android:textSize="24sp"
android:background="@drawable/shape_background"
/>
</FrameLayout>
item_channel_selected选择
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingLeft="4dp"
android:paddingBottom="4dp"
android:paddingRight="4dp"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="频道管理"
android:gravity="center_horizontal"
android:textSize="24sp"
android:background="@drawable/shape_background"
/>
</FrameLayout>
item_channel_title标题
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text"
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:text="标题"
android:textColor="@android:color/black"
android:textSize="28sp"
>
</TextView>
item_text文本
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text"
android:padding="16dp"
android:textSize="24sp"
>
</TextView>
MainActivity页面
package com.example.text_1120;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView contents;
private ChannelManagerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contents=findViewById(R.id.contents);
//优化
contents.setHasFixedSize(true);
adapter=new ChannelManagerAdapter(this);
//布局管理器
GridLayoutManager manager=new GridLayoutManager(this,4);
//item跨列显示
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int i) {
return adapter.isTitle(i)?4:1;
}
});
contents.setLayoutManager(manager);
adapter.setOnItemClickListener(new ChannelManagerAdapter.OnItemClickListener() {
@Override
public void onItemClick(View itemView, int position) {
if(position < 0) {
Toast.makeText(MainActivity.this, "太快啦", Toast.LENGTH_LONG).show();
return;
}
if (!isEditMode&&adapter.isSelectedChannel(position)){
Toast.makeText(MainActivity.this,"选中了条目,返回:"+position,Toast.LENGTH_LONG).show();
return;
}
//移除
ChannelManagerBean removeBean=adapter.removeItem(position);
removeBean.setSelected(!removeBean.isSelected());
//添加
adapter.addItem(removeBean);
}
});
contents.setAdapter(adapter);
loadData();
}
private void loadData() {
List<ChannelManagerBean> selectedDatas=new ArrayList<>();
List<ChannelManagerBean> normalDatas=new ArrayList<>();
selectedDatas.add(new ChannelManagerBean("关注",true,false));
selectedDatas.add(new ChannelManagerBean("推荐",true,false));
selectedDatas.add(new ChannelManagerBean("科学",true,false));
selectedDatas.add(new ChannelManagerBean("美食",true,false));
selectedDatas.add(new ChannelManagerBean("养生",true,false));
selectedDatas.add(new ChannelManagerBean("电影",true,false));
selectedDatas.add(new ChannelManagerBean("生活",true,false));
selectedDatas.add(new ChannelManagerBean("搞笑",true,false));
selectedDatas.add(new ChannelManagerBean("懂车",true,false));
selectedDatas.add(new ChannelManagerBean("军事",true,false));
selectedDatas.add(new ChannelManagerBean("党媒",true,false));
selectedDatas.add(new ChannelManagerBean("历史",true,false));
selectedDatas.add(new ChannelManagerBean("体育",true,false));
normalDatas.add(new ChannelManagerBean("宠物",false,true));
normalDatas.add(new ChannelManagerBean("娱乐",false,true));
normalDatas.add(new ChannelManagerBean("财经",false,true));
normalDatas.add(new ChannelManagerBean("直播",false,true));
normalDatas.add(new ChannelManagerBean("特卖",false,true));
normalDatas.add(new ChannelManagerBean("房产",false,true));
normalDatas.add(new ChannelManagerBean("小说",false,true));
normalDatas.add(new ChannelManagerBean("时尚",false,true));
normalDatas.add(new ChannelManagerBean("音频",false,true));
normalDatas.add(new ChannelManagerBean("育儿",false,true));
normalDatas.add(new ChannelManagerBean("数码",false,true));
normalDatas.add(new ChannelManagerBean("健康",false,true));
normalDatas.add(new ChannelManagerBean("手机",false,true));
normalDatas.add(new ChannelManagerBean("传媒",false,true));
normalDatas.add(new ChannelManagerBean("星座",false,true));
normalDatas.add(new ChannelManagerBean("精选",false,true));
normalDatas.add(new ChannelManagerBean("收藏",false,true));
normalDatas.add(new ChannelManagerBean("故事",false,true));
adapter.setChannelDatas(selectedDatas,normalDatas);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu,menu);
return true;
}
private boolean isEditMode=false;
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==R.id.e_action){
isEditMode=!isEditMode;
item.setTitle(isEditMode?"完成":"编辑");
return true;
}
return super.onOptionsItemSelected(item);
}
}
ChannelManagerBean
package com.example.text_1120;
public class ChannelManagerBean {
//名称
private String name;
//是否选择的频道
private boolean isSelected;
//是否当前的频道
private boolean isCurrent;
//是否固定不能更改
private boolean isFixted;
public ChannelManagerBean(String name, boolean isSelected, boolean isCurrent) {
this.name = name;
this.isSelected = isSelected;
this.isCurrent = isCurrent;
}
public String getName(){
return !isSelected?"+"+name:name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public boolean isCurrent() {
return isCurrent;
}
public void setCurrent(boolean current) {
isCurrent = current;
}
public boolean isFixted() {
return isFixted;
}
public void setFixted(boolean fixted) {
isFixted = fixted;
}
}
ChannelManagerAdapter适配器
package com.example.text_1120;
import android.content.Context;
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;
import java.util.ArrayList;
import java.util.List;
public class ChannelManagerAdapter extends RecyclerView.Adapter<ChannelManagerAdapter.ViewHolder> {
private List<ChannelManagerBean> selectedChange;
private List<ChannelManagerBean> normalChange;
private Context context;
public ChannelManagerAdapter(Context context) {
this.context = context;
selectedChange=new ArrayList<>();
normalChange=new ArrayList<>();
}
@Override
public int getItemViewType(int position) {
if (isTitle(position)){
return R.layout.item_change_title;
}
if (isSelectedChannel(position)){
return R.layout.item_change_selected;
}
return R.layout.item_change_normal;
}
public ChannelManagerBean getItem(int position){
if (isTitle(position)){
return null;
}
//第一个选中频道列表的数据
if (isSelectedChannel(position)){
return selectedChange.get(position-1);
}
//第二个未选中批到列表的数据
return normalChange.get(position - selectedChange.size()-2);
}
//是否是选中频道的标题
boolean isTitle(int position) {
return isSelTitle(position)||isNomTitle(position);
}
//当前频道是否是选中的频道
public boolean isSelectedChannel(int position){
return position<=selectedChange.size();
}
//是否是普通的标题
private boolean isNomTitle(int position) {
return position==selectedChange.size()+1;
}
//是否是选中的标题
private boolean isSelTitle(int position) {
return position==0;
}
public void setChannelDatas(List<ChannelManagerBean> selectedChange,List<ChannelManagerBean> normalChange) {
this.selectedChange = selectedChange;
this.normalChange=normalChange;
notifyDataSetChanged();
}
public ChannelManagerBean removeItem(int position){
ChannelManagerBean channelManagerBean=null;
if (isSelectedChannel(position)){
channelManagerBean=selectedChange.remove(position-1);
}else {
channelManagerBean=normalChange.remove(position-selectedChange.size()-2);
}
notifyItemRemoved(position);
return channelManagerBean;
}
public void addItem(ChannelManagerBean item){
if (item.isSelected()){
selectedChange.add(item);
notifyItemInserted(selectedChange.size());
}else {
normalChange.add(0,item);
notifyItemInserted(selectedChange.size()+2);
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
if (i==R.layout.item_change_title){
return new ViewHolder(LayoutInflater.from(context).inflate(i,viewGroup,false));
}else{
return new ViewHolder(LayoutInflater.from(context).inflate(i,viewGroup,false), listener);
}
}
@Override
public void onBindViewHolder(@NonNull ChannelManagerAdapter.ViewHolder viewHolder, int i) {
if (isSelTitle(i)){
viewHolder.text.setText("我的频道");
return;
}
if (isNomTitle(i)){
viewHolder.text.setText("频道管理");
return;
}
viewHolder.text.setText(getItem(i).getName());
}
@Override
public int getItemCount() {
return selectedChange.size()+normalChange.size()+2;
}
private OnItemClickListener listener;
public ChannelManagerAdapter setOnItemClickListener(OnItemClickListener listener){
this.listener=listener;
return this;
}
public interface OnItemClickListener{
void onItemClick(View itemView,int position);
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView text;
public ViewHolder(@NonNull View itemView) {
super(itemView);
text=itemView.findViewById(R.id.text);
}
public ViewHolder(View itemView,final OnItemClickListener listener){
this(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener==null){
return;
}
listener.onItemClick(ViewHolder.this.itemView,getAdapterPosition());
}
});
}
}
}
Shape矩形边角
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
>
<solid android:color="#ffffff"
/>
<stroke android:width="1dp"
android:color="#00ffff"/>
<corners
android:radius="8dp"
/>
</shape>
Menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/e_action" android:title="编辑" app:showAsAction="always"/>
</menu>