Android BaseQuickAdapter万能适配器

2023-11-06

RecycleView万能适配器

一导入

  • implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.24'
  • implementation 'com.android.support:recyclerview-v7:25.3.1'
allprojects {
        repositories {
            ...
            maven { url "https://jitpack.io" }
        }
    }

二:基本应用

  1. activity_main xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>

2.条目布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dp">



    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:text="我是标题"
        android:textColor="#f00"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/tv_title"
        android:layout_marginLeft="10dp"
        android:textSize="20dp"
        android:layout_marginTop="10dp"
        android:text="我年龄" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_title"
        android:textSize="18dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:text="我是描述" />
</RelativeLayout>

3.编写数据实体类型

public class Person {
    private String name;
    private int age;
    private String des;
    
   生成 get set方法
}

  1. 编写适配器
public class QuickAdapter extends BaseQuickAdapter<Person, BaseViewHolder> {

    private Context context;

    public QuickAdapter(int layoutResId, @Nullable List<Person> data, Context context) {
        super(layoutResId, data);
        this.context = context;
    }

    @SuppressLint("ResourceAsColor")
    @Override
    protected void convert(@NonNull BaseViewHolder helper, Person item) {
        helper.setText(R.id.tv_title, item.getName()+"")
                .setTextColor(R.id.tv_title, context.getResources().getColor(R.color.colorPrimary))
                .setText(R.id.tv_age, item.getAge()+"")
                .setText(R.id.tv_content, item.getDes()+"")
                .setTextColor(R.id.tv_content, context.getResources().getColor(R.color.colorAccent));

    }
}

5: 最后一步:在Activity中使用该适配器

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private QuickAdapter adapter;
    private ArrayList<Person> list;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView =findViewById(R.id.recycler_view);
        list =new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Person person =new Person();
            person.setAge(i);
            person.setName("我是第"+i+"条数据");
            person.setDes("我是描述"+i);
            list.add(person);
        }
        LinearLayoutManager manager =new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);

        adapter =new QuickAdapter(R.layout.item_rv,list,this);
        recyclerView.setAdapter(adapter);
    }
}

三:点击事件
1:Item的点击事件

 adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                Toast.makeText(MainActivity.this, "点击了第"+position+"条目", Toast.LENGTH_SHORT).show();
            }
        });

2:长按点击事件

adapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
                Toast.makeText(MainActivity.this, "长按"+position+"条目", Toast.LENGTH_SHORT).show();
                return false;
            }
        });

3:条目子控件事件
首先,在adapter的convert方法里面通过 helper.addOnClickListener 绑定一下子控件的控件id

 @SuppressLint("ResourceAsColor")
    @Override
    protected void convert(@NonNull BaseViewHolder helper, Person item) {
        helper.setText(R.id.tv_title, item.getName()+"")
                .setTextColor(R.id.tv_title, context.getResources().getColor(R.color.colorPrimary))
                .setText(R.id.tv_age, item.getAge()+"")
                .setText(R.id.tv_content, item.getDes()+"")
                .setTextColor(R.id.tv_content, context.getResources().getColor(R.color.colorAccent))
                .addOnClickListener(R.id.tv_title); //给标题增加点击事件
    }

然后设置

 //条目子控件事件
        adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                //多个事件
                Toast.makeText(MainActivity.this, "标题子控件点击"+position+"条目", Toast.LENGTH_SHORT).show();
                }
            }
        });

4:Item子控件的长按事件 跟点击条目控件事件做法相同
5:多个Item子控件事件
首先绑定

 @SuppressLint("ResourceAsColor")
    @Override
    protected void convert(@NonNull BaseViewHolder helper, Person item) {
        helper.setText(R.id.tv_title, item.getName()+"")
                .setTextColor(R.id.tv_title, context.getResources().getColor(R.color.colorPrimary))
                .setText(R.id.tv_age, item.getAge()+"")
                .setText(R.id.tv_content, item.getDes()+"")
                .setTextColor(R.id.tv_content, context.getResources().getColor(R.color.colorAccent))
                .addOnClickListener(R.id.tv_title) //给标题增加点击事件
                .addOnClickListener(R.id.tv_content)给描述增加点击事件;
              
    }

然后区分id

 adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                //多个事件
                switch (view.getId()){
                    case R.id.tv_title:
                        Toast.makeText(MainActivity.this, "标题子控件点击"+position+"条目", Toast.LENGTH_SHORT).show();
                      
                        break;
                    case R.id.tv_content:
                        Toast.makeText(MainActivity.this, "描述子控件点击"+position+"条目", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });

那么如果是长按事件呢?当然也是相同的处理方法。

6如果需要在子控件事件中获取其他子控件可以使用:

getViewByPosition(RecyclerView recyclerView, int position, @IdRes int viewId)
 adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                //多个事件
                switch (view.getId()){
                    case R.id.tv_title:
                        Toast.makeText(MainActivity.this, "标题子控件点击"+position+"条目", Toast.LENGTH_SHORT).show();
                        // TODO 子控件事件中获取其他子控件可以使用
                        //TODO getViewByPosition(RecyclerView recyclerView, int position, @IdRes int viewId)
                        TextView tv_title = (TextView) adapter.getViewByPosition(recyclerView, position, R.id.tv_title);
                        Log.e("wudi", "onItemChildClick: tv_title.getText()="+tv_title.getText() );
                        TextView tv_content = (TextView) adapter.getViewByPosition(recyclerView, position, R.id.tv_content);
                        Log.e("wudi", "onItemChildClick: tv_content.getText()="+tv_content.getText() );
                        break;
                    case R.id.tv_content:
                        Toast.makeText(MainActivity.this, "描述子控件点击"+position+"条目", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });

四、添加列表加载动画
1://开启动画(默认为渐显效果)
adapter.openLoadAnimation();
2:五种状态 (渐显、缩放、从下到上,从左到右、从右到左)

public static final int ALPHAIN = 0x00000001;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SCALEIN = 0x00000002;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_BOTTOM = 0x00000003;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_LEFT = 0x00000004;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_RIGHT = 0x00000005;

//使用缩放
adapter.openLoadAnimation(BaseQuickAdapter.SCALEIN);

如果想自定义动画,该适配器也提供了接口

//自定义动画效果
        adapter.openLoadAnimation(new BaseAnimation() {
            @Override
            public Animator[] getAnimators(View view) {
                return new Animator[]{
                        ObjectAnimator.ofFloat(view, "scaleY", 1, 0.5f, 1),
                        ObjectAnimator.ofFloat(view, "scaleX", 1, 0.5f, 1)
                };
            }
        });

动画默认只执行一次,如果想重复执行可设置

//设置重复执行动画
adapter.isFirstOnly(false);

设置不显示动画数量(老实讲,我没明白这个方法的效果是啥,因为我并没有看到效果 0.0

adapter.setNotDoAnimationCount(count);

首次到界面的item每次都依次执行加载动画
由于进入界面的item都是很多的速度进来的所以不会出现滑动显示的依次执行动画效果,这个时候会一起执行动画,如果觉得这样的效果不好可以使用setNotDoAnimationCount设置第一屏item不执行动画,但是如果需要依次执行动画可以重写startAnim让第一个屏幕的item动画延迟执行即可。

@Override
    protected void startAnim(Animator anim, int index) {
        super.startAnim(anim, index);
        if (index < count)
        anim.setStartDelay(index * 150);
    }

五:添加头部、尾部

    	View headView = View.inflate(MainActivity.this, R.layout.head_view, null);
        View footView = View.inflate(MainActivity.this, R.layout.foot_view, null);
        adapter.addHeaderView(headView);
        adapter.addFooterView(footView);

删除指定view

        adapter.removeHeaderView(headView);
        adapter.removeFooterView(footView);

删除所有布局

		adapter.removeAllHeaderView();
        adapter.removeAllFooterView();

出现了头布局就不会显示Empty

adapter.setHeaderAndEmpty(true);
adapter.setHeaderFooterEmpty(true,true);

六、上拉加载
1:创建一个数据管理

public class DataServer {

    //分页加载数据
    public static List<Person> getData(int lenth) {
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < lenth; i++) {
            Person person = new Person();
            person.setName("name"+i);
            person.setDes("描述"+i);
            person.setAge(i);
            list.add(person);
        }
        return list;
    }
}

2:设置上啦加载

	//当前个数
    private  int mCurrentCounter =0;
    //总数
    private  int TOTAL_COUNTER =100;
    //每次取多少个
    private  int PAGE_SIZE =10;
    //是否加载失败
    private boolean isErr =true;

 adapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                recyclerView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (mCurrentCounter >= TOTAL_COUNTER) {
                            //数据全部加载完毕
                            adapter.loadMoreEnd();
                        } else {
                            if (isErr) {
                                //成功获取更多数据(可以直接往适配器添加数据)
                                adapter.addData(DataServer.getData(PAGE_SIZE));
                                mCurrentCounter = adapter.getData().size();
                                //主动调用加载完成,停止加载
                                adapter.loadMoreComplete();
                            } else {
                                //获取更多数据失败
                                isErr = true;
                                Toast.makeText(MainActivity.this, R.string.network_err, Toast.LENGTH_LONG).show();
                                //同理,加载失败也要主动调用加载失败来停止加载(而且该方法会提示加载失败)
                                adapter.loadMoreFail();

                            }
                        }
                    }

                }, 300);
            }
        },recyclerView);

加载完成(注意不是加载结束,而是本次数据加载结束并且还有下页数据)

 adapter.loadMoreComplete()

加载失败

adapter.loadMoreFail();

加载结束

adapter.loadMoreEnd();

注意:如果上拉结束后,下拉刷新需要再次开启上拉监听,需要使用setNewData方法填充数据。
打开或关闭加载(一般用于下拉的时候做处理,因为上拉下拉不能同时操作)

adapter.setEnableLoadMore(boolean);

预加载(这个功能屌炸天)

// 当列表滑动到倒数第N个Item的时候(默认是1)回调onLoadMoreRequested方法
adapter.setPreLoadNumber(int);
adapter.setPreLoadNumber(3);

设置自定义加载布局

adapter.setLoadMoreView(new CustomLoadMoreView());

public final class CustomLoadMoreView extends LoadMoreView {

    @Override
    public int getLayoutId() {
        return R.layout.view_load_more;
    }

    /**
     * 如果返回true,数据全部加载完毕后会隐藏加载更多
     * 如果返回false,数据全部加载完毕后会显示getLoadEndViewId()布局
     */
    @Override
    public boolean isLoadEndGone() {
        return true;
    }

    @Override
    protected int getLoadingViewId() {
        return R.id.load_more_loading_view;
    }

    @Override
    protected int getLoadFailViewId() {
        return R.id.load_more_load_fail_view;
    }

    /**
     * isLoadEndGone()为true,可以返回0
     * isLoadEndGone()为false,不能返回0
     */
    @Override
    protected int getLoadEndViewId() {
        return 0;
    }
}

七、下拉加载(符合聊天软件下拉历史数据需求)

mAdapter.setUpFetchEnable(true);
mAdapter.setUpFetchListener(new BaseQuickAdapter.UpFetchListener() {
            @Override
            public void onUpFetch() {
                startUpFetch();
            }
        });
private void startUpFetch() {
        count++;
        /**
         * set fetching on when start network request.
         */
        mAdapter.setUpFetching(true);
        /**
         * get data from internet.
         */
        mRecyclerView.postDelayed(new Runnable() {
            @Override
            public void run() {
                mAdapter.addData(0, genData());
                /**
                 * set fetching off when network request ends.
                 */
                mAdapter.setUpFetching(false);
                /**
                 * set fetch enable false when you don't need anymore.
                 */
                if (count > 5) {
                    mAdapter.setUpFetchEnable(false);
                }
            }
        }, 300);
    }

八:多布局
1:实体类

public class Person {
    private String name;
    private int age;
    private String des;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }
}

2:多布局设置类型 MultipleItem implements MultiItemEntity

/**
 * 多布局展示
 * */
//实体类必须实现MultiItemEntity,在设置数据的时候,需要给每一个数据设置itemType
public class MultipleItem implements MultiItemEntity {

    public static final int FIRST_TYPE = 1;
    public static final int SECOND_TYPE = 2;
    public static final int NORMAL_TYPE = 3;

    private int itemType;
    private Person person;

    public MultipleItem(int itemType, Person person) {
        this.itemType = itemType;
        this.person = person;
    }

    @Override
    public int getItemType() {
        return itemType;
    }
    public Person getPerson(){
        return person;
    }
}

3:适配器 继承 BaseMultiItemQuickAdapter
addItemType 区分类型
helper.getItemViewType() 实现多布局展示

/**
 * 多布局adapter
 * */
public class MoreQuickAdapter extends BaseMultiItemQuickAdapter<MultipleItem, BaseViewHolder> {

    private Context context;

    public MoreQuickAdapter(List<MultipleItem> data, Context context) {
        super(data);
        this.context = context;
        addItemType(MultipleItem.FIRST_TYPE, R.layout.first_type_layout);
        addItemType(MultipleItem.SECOND_TYPE, R.layout.second_type_layout);
        addItemType(MultipleItem.NORMAL_TYPE, R.layout.item_rv);
    }

    @Override
    protected void convert(@NonNull BaseViewHolder helper, MultipleItem item) {

        switch (helper.getItemViewType()) {
            case MultipleItem.FIRST_TYPE:
                helper.setText(R.id.tv_title,item.getPerson().getName()+"布局一")
                        .setTextColor(R.id.tv_title,context.getResources().getColor(R.color.colorAccent))
                        .setText(R.id.tv_age,item.getPerson().getAge()+"")
                        .setTextColor(R.id.tv_age,context.getResources().getColor(R.color.colorAccent))
                        .setText(R.id.tv_content,item.getPerson().getDes()+"")
                        .setTextColor(R.id.tv_content,context.getResources().getColor(R.color.colorAccent));
                break;
            case MultipleItem.SECOND_TYPE:
                helper.setText(R.id.tv_title,item.getPerson().getName()+"布局二")
                        .setTextColor(R.id.tv_title,context.getResources().getColor(R.color.colorPrimary))
                        .setText(R.id.tv_age,item.getPerson().getAge()+"")
                        .setTextColor(R.id.tv_age,context.getResources().getColor(R.color.colorPrimary))
                        .setText(R.id.tv_content,item.getPerson().getDes()+"")
                        .setTextColor(R.id.tv_content,context.getResources().getColor(R.color.colorPrimary));
                break;
            case MultipleItem.NORMAL_TYPE:
                helper.setText(R.id.tv_title,item.getPerson().getName()+"正常")
                        .setTextColor(R.id.tv_title,context.getResources().getColor(R.color.color1bd))
                        .setText(R.id.tv_age,item.getPerson().getAge()+"")
                        .setTextColor(R.id.tv_age,context.getResources().getColor(R.color.color1bd))
                        .setText(R.id.tv_content,item.getPerson().getDes()+"")
                        .setTextColor(R.id.tv_content,context.getResources().getColor(R.color.color1bd));
                break;
        }
    }
}

4:activity

 	private RecyclerView recyclerView;
    private ArrayList<Person> data;
    private ArrayList<MultipleItem> multipleItems;
    private MoreQuickAdapter adapter;
		recyclerView =findViewById(R.id.recycler_view);
        data =new ArrayList<>();
        multipleItems =new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            Person person =new Person();
            person.setAge(i);
            person.setName("name"+i);
            person.setDes("描述"+i);
            data.add(person);
        }
        //这里我是随机给某一条目加载不同的布局
        for (int i = 0; i < 30; i++) {
            if (i % 3 == 0) {
                multipleItems.add(new MultipleItem(MultipleItem.FIRST_TYPE, data.get(i)));
            } else if (i % 7 == 0) {
                multipleItems.add(new MultipleItem(MultipleItem.SECOND_TYPE, data.get(i)));
            } else {
                multipleItems.add(new MultipleItem(MultipleItem.NORMAL_TYPE, data.get(i)));
            }
        }

        LinearLayoutManager manager =new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);
        adapter =new MoreQuickAdapter(multipleItems,this);
        recyclerView.setAdapter(adapter);

十:添加拖拽、滑动删除
拖拽和滑动删除的回调方法:

public class ItemDragAdapter extends BaseItemDraggableAdapter<Person,BaseViewHolder> {

    public ItemDragAdapter(int layoutResId, List<Person> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(@NonNull BaseViewHolder helper, Person item) {
        helper.setText(R.id.tv_title,item.getName()+"")
                .setText(R.id.tv_age,item.getAge()+"")
                .setText(R.id.tv_content,item.getDes()+"");

    }
}

activity:

 LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);

        adapter = new ItemDragAdapter(R.layout.second_type_layout,data);

        ItemDragAndSwipeCallback itemDragAndSwipeCallback = new ItemDragAndSwipeCallback(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);
        itemTouchHelper.attachToRecyclerView(recyclerView);

        // 开启拖拽
        adapter.enableDragItem(itemTouchHelper, R.id.rl_layout, true);
        adapter.setOnItemDragListener(onItemDragListener);

        // 开启滑动删除
        adapter.enableSwipeItem();
        adapter.setOnItemSwipeListener(onItemSwipeListener);

        recyclerView.setAdapter(adapter);
 OnItemDragListener onItemDragListener =new OnItemDragListener() {
        @Override
        public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("wudi", "onItemDragStart: "+pos );
        }

        @Override
        public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
            Log.e("wudi", "onItemDragMoving: from="+from+",to="+to );
        }

        @Override
        public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("wudi", "onItemDragEnd: "+pos );
        }
    };
    OnItemSwipeListener  onItemSwipeListener =new OnItemSwipeListener () {

        @Override
        public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {
            Log.e("wudi", "onItemSwipeStart: "+pos );
        }

        @Override
        public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {

        }

        @Override
        public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {

        }

        @Override
        public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {

        }
    };

新增
适配器设置数据,设置点击固定数据的点击事件

   Log.e(TAG, "convert:helper.getLayoutPosition()= "+helper.getLayoutPosition() );
        switch (helper.getLayoutPosition() % 3) {
            case 0:
                helper.setImageResource(R.id.image, R.mipmap.animation_img1);
                break;
            case 1:
                helper.setImageResource(R.id.image, R.mipmap.animation_img2);
                break;
            case 2:
                helper.setImageResource(R.id.image, R.mipmap.animation_img3);
                break;
            default:
                break;
        }
 /**
         * 设置tv_title 样式
         * */
        helper.setText(R.id.tv_title,SpannableStringUtils.getBuilder(item.getName()).append("landscapes and nedes")
                    .setClickSpan(clickableSpan)
                    .setBoldItalic()
                .setProportion(1.5f)
                .setStrikethrough()
                .setUnderline()
                .setSuperscript()
                .setSubscript()
                .setQuoteColor(R.color.color1bd)
                .create()); //给标题增加点击事件;
        ((TextView) helper.getView(R.id.tv_title)).setMovementMethod(ClickableMovementMethod.getInstance());
        ((TextView) helper.getView(R.id.tv_title)).setFocusable(false);
        ((TextView) helper.getView(R.id.tv_title)).setClickable(false);
        ((TextView) helper.getView(R.id.tv_title)).setLongClickable(false);
//点击
 private ClickableSpan clickableSpan = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            ToastUtils.showShortToast("事件触发了 landscapes and nedes");
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(content.getResources().getColor(R.color.colorAccent));
            ds.setUnderlineText(true);
        }
    };
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android BaseQuickAdapter万能适配器 的相关文章

随机推荐

  • 一文让前端搞懂shell编程

    概述 前端程序员有时会遇到部署项目的情况 有时需要看懂后台或者运维写的脚本 如果转型AI 数据分析和模型训练也经常用到shell编程 掌握shell编程 你的编程之路会越走越宽 shell 解析器 sudo cat etc shells t
  • Win7下使用U盘安装Ubuntu16.04双系统图文教程(亲测)

    安装步骤 1 下载Ubuntu 16 04镜像软件 2 使用ultraISO软件制作U盘启动盘 3 利用U盘启动盘来安装Ubuntu系统 4 使用EasyBCD创建启动系统启动引导 可以省略 5 重启系统即可 一 下载ubuntu16 04
  • 使用Semaphore 实现一个简单的限流器

    使用Semaphore 实现一个简单的限流器 java api Java的api中 提供了semaphore这个线程同步的辅助类 用来控制同时访问共享资源的线程数量 Semaphore提供的主要方法如下 void acquire 获取一个信
  • NUC10 i7 黑苹果Big Sur 11.4 + win10 双系统安装指南

    说明 硬件 Intel NUC 10代 i7 10710U 系统说明 Mac OS Big Sur 11 4 Windows 10 注 本文默认已经安装好windows 安装过程就和普通的单系统安装步骤一样 安装步骤略 其他说明 由于个人知
  • 协同过滤与矩阵分解

    协同过滤算法的基本原理 用户行为数据是推荐系统最常用 也是最关键的数据 用户的潜在兴趣 用户对物品的评价好坏都反映在用户的行为历史中 而协同过滤算法 就是一种完全依赖用户和物品之间行为关系的推荐算法 我们从它的名字 协同过滤 中 也可以窥探
  • 2022高教杯思路合集!!全国大学生数学建模竞赛

    2022高教杯将于9 15开赛 思路贴将于晚10点前发布 粉丝可见 17日0 00转免 国一F奖3年数学建模经验团队 交流Q群 882663918 下文是2022年美赛的思路示例 要求由于公司的规定 ICM公司无法与您的团队分享关于他们的人
  • android 全局悬浮窗 可点击_Hi Translate 全局翻译外语 App 上的内容

    英文不太好的朋友可能在使用某些国外 App 在无中文语言支持的时候 也许 Hi Translate 这款 Android 应用可以帮助到你 这款应用不是简单的外语翻译 它可以在你使用满是外语的 App 时 帮助你实现全局页面翻译成中文 Hi
  • IDEA 集成 Sonar 完整流程

    目录 背景 相关的模块及关系 插件安装 SonarQube 启动 SonarQube 创建工程 插件配置 1 打开插件通用配置界面 2 点击 号添加 SonarServer 3 下一步配置认证信息 4 SonarLint 项目配置 mave
  • C++ char*两种初始化为零的方式

    C 中 char 两种初始化为零的的常用方式有以下两种 char data new char 50 char data memset data 0 50
  • ios-消息中心 NSNotificationCenter 的介绍

    1 通知中心概述 通知中心实际上是在程序内部提供了消息广播的一种机制 通知中心不能在进程间进行通信 实际上就是一个二传手 把接收到的消息 根据内部的一个消息转发表 来将消息转发给需要的对象 通知中心是基于观察者模式的 它允许注册 删除观察者
  • C++17入门经典

    C 17入门经典 注意 第1章 基本概念 第2章 基本数据类型 第3章 处理基本数据类型 第4章 决策 第5章 数组和循环 第6章 指针和引用 第7章 操作字符串 第8章 定义函数 第9章 函数模板 第10章 程序文件和预处理指令 第11章
  • python 修饰器 参数_Python修饰器讲解

    转自 http www cnblogs com rollenholt archive 2012 05 02 2479833 html 文章先由stackoverflow上面的一个问题引起吧 如果使用如下的代码 makebold makeit
  • 语义分割--PANet和Understanding Convolution for Semantic Segmentation

    语义分割 PAN Pyramid Attention Network for Semantic Segmentation FCN作为backbone的结构对小型目标预测不佳 论文认为这存在两个挑战 物体因为多尺度的原因 造成难以分类 针对这
  • J2EE规范技术

    原文 http blog csdn net erikxu archive 2004 12 07 208170 aspx J2EE的13种核心技术 1 JDBC Java Data Base Connectivity java数据库连接 是一
  • Unity3D 中使用OnTiggerEnter遇到的不触发问题

    移动GameObject 绑定BoxCollider Istrigger选中 固定GameObject 绑定BoxCollider 刚体属性 IsKinematic选中 此种情况下 移动GameObject中的OnTriggerEnter
  • 数据结构(1)前言

    1 学习数据结构前 需要掌握结构体和指针的使用 需要了解typedef这个关键字 对这部分知识欠缺的可以查看 C语言结构体详解 何为指针 与数组名有什么区别 2 作为一名想成为嵌入式软件工程师的人而言 很多像电气工程 电子信息等专业的人在大
  • Windows11 文件选择打开方式时卡死 解决

    发生的现象 在 打开方式 窗口的地址栏粘贴应用的地址 gt 打开方式界面卡死 完整步骤 左键点击打开epub文件 gt 跳出 寻找一个应用以打开此 epub文件 gt 选择 在电脑上选择应用 gt 弹出 打开方式 窗口 gt 在 打开方式
  • ❤ 15个基于Vue3.0全家桶的优秀开源项目

    15个基于Vue3 0全家桶的优秀开源项目 Vue Admin Better github https github com chuzhixin vue admin better vue admin better 对比其他来源 admin
  • 雨停了,我将雨伞收起

    天空中已有阳光从厚重的云层间隙射向大地 我将手中的雨伞收起 伞面上留存着的雨滴正沿着伞面的褶皱流下打在地上 我望向远方 一辆汽车沿着自己的轨迹行驶 路边小坑中的积水在车轮的驱赶下纷纷跳上灌木丛的绿叶寻找庇护 一阵清脆的自行车铃在身后响起 一
  • Android BaseQuickAdapter万能适配器

    RecycleView万能适配器 一导入 implementation com github CymChad BaseRecyclerViewAdapterHelper 2 9 24 implementation com android s