RecyclerView介绍

RecyclerView的出现可以替代ListView,并且比ListView更高级且更具灵活性。如果有数据集合,其中的元素将因用户操作或网络事件而在运行时发生改变,请使用RecyclerVIew。

在ListVIew中,改变列表某一个item数据,然后刷新列表,会回到最顶部,而RecyclerView可以保持原来滑动的位置不变。

RecyclerView实现

要实现一个RecyclerView,会引用到其它模块,其中1、 2是必须的。剩下的3、 4、 5三项,则是起到美化装饰的效果。

1. 控制item的排列方式,需用到布局管理器LayoutManager。

2. 创建一个适配器,需用到RecyclerView.Adapter。

3. 控制item间的间隔,需用到RecyclerView.ItemDecoration。

4. 控制item增删的动画,需用到RecyclerView.ItemAnimator。

5. CardView扩展FrameLayout类,可以显示卡片内的信息,这些信息在整个平台中拥有一致的呈现方式。CardView小部件可拥有阴影和圆角。

注:如果要使用RecyclerView小部件,必须要指定一个Adapter和一个LayoutManager。

RecyclerView简单实例

先感受一下怎么使用RecyclerView。

第一步:新建一个empty Activity。(不赘述,不知道的可以看https://www.cnblogs.com/smart-zihan/p/9813940.html)

第二步:在activity_main.xml中添加一个RecyclerView。

刚开始在右边会有一个下载的符号,点击它下载就好,然后将其拖动到

之后gradle sync,其实这个步骤就是在gradle文件中添加了RecyclerView包。

implementation 'com.android.support:recyclerview-v7:28.0.0'

附上activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/recycleview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/> </LinearLayout>

第三步:在MainActivity.java中使用它。

        //通过findViewById拿到RecycleView实例
mRecycleView = findViewById(R.id.recycleview);
//设置RecyclerView管理器
mRecycleView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));

第四步:新建Adapter类,item.xml并在MainActivity中引入使用它。

Adapter类:

package com.example.aimee.callbacktest;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private static final String TAG = "MyAdapter";//可以用来debug
private String[] mTitles;
private final Context mContext;
private final LayoutInflater mLayoutInflater; public static class ViewHolder extends RecyclerView.ViewHolder{
TextView mTextView;
public ViewHolder(View v){
super(v);
mTextView = (TextView) v.findViewById(R.id.item_tx);
v.setOnClickListener(new View.OnClickListener() {//当点击item时,会产生什么事件
@Override
public void onClick(View v) {
Log.d(TAG,"onClick-->position = " + getAdapterPosition());
}
});
}
} public MyAdapter(Context context) {
mTitles = context.getResources().getStringArray(R.array.titles);//items
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
} @Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(mTitles[position]); } @Override
public int getItemCount() {
return mTitles == null?0:mTitles.length;
} @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//LayoutInflater.from指定写法
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_normal, parent, false);
return new ViewHolder(v);
}
}

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical"> <TextView
android:id="@+id/item_tx"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:layout_gravity="center_horizontal"
android:text="item"/> </LinearLayout>

MainActivity.java引用Adapter类

        //初始化适配器
myAdapter = new MyAdapter(this);
//设置适配器
mRecycleView.setAdapter(myAdapter);

最后,附上完整MainActivity.java代码:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; public class MainActivity extends AppCompatActivity { public String TAG = "RECYCLE";
private RecyclerView mRecycleView;
private MyAdapter myAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //通过findViewById拿到RecycleView实例
mRecycleView = findViewById(R.id.recycleview);
//设置RecyclerView管理器
mRecycleView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
//初始化适配器
myAdapter = new MyAdapter(this);
//设置适配器
mRecycleView.setAdapter(myAdapter);
}
}

效果图:

围绕这个例子,介绍一下其它的模块:

一、LayoutManager

布局管理器,来控制Item的排列方式。

RecyclerView提供的布局管理器:

  • LinearLayoutManager:以垂直或水平滚动列表方式显示项目。例子中以引用。
  • GridLayoutManager:在网络中显示项目。用法:mRecycleView.setLayoutManager(new GridLayoutManager(getBaseContext(),3));
  • StaggeredGridLayoutManager:在分散对齐网络中显示项目。用法:mRecycleView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));

二、Adapter

myAdapter = new MyAdapter(this);

数据适配器与BaseAdapter比较发生了相当大的变化,主要有三个方法:

  1. getItemCount():获取总的条目数
  2. onCreateViewHolder():创建ViewHolder
  3. onBindVIewHolder():将数据绑定至ViewHolder

创建ViewHolder必须继承RecyclerView.ViewHolder,RecyclerView.ViewHolder构造时必须传入一个View,即item布局。在RecyclerView中,把ViewHolder类作为缓存的单位,假设屏幕显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder。方法是onCreateViewHolder。

瀑布式布局

在Adapter的onBindViewHolder()为item设置个随机的高度,下面给出Adapter中添加的代码:

    public MyAdapter(Context context){
mTitles = context.getResources().getStringArray(R.array.item_list);
mLayoutInflater = LayoutInflater.from(context);
mcontext = context;
mHeights = new ArrayList<Integer>(); for (int i=0;i<mTitles.length;i++){
mHeights.add((int) (100 + Math.random() * 300));
}
}
    @Override
public void onBindViewHolder(ViewHolder holder,int position){
ViewGroup.LayoutParams lp = holder.mTextView.getLayoutParams();
lp.height = mHeights.get(position); holder.mTextView.setLayoutParams(lp);
holder.mTextView.setText(mTitles[position]);
}

效果图:

这个是在string.xml中定义的item,如果我们要直接在MainActivity中定义列表怎么办呢?可用如下Adapter和在MainActivity中添加列表的方式.

WaterpallStaggeredAdapter:
package com.example.aimee.callbacktest;

import android.content.Context;
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 WaterpallStaggeredAdapter extends RecyclerView.Adapter<WaterpallStaggeredAdapter.MyViewHolder> { private List<String> mDatas;
private LayoutInflater mInflater;
private List<Integer> mHeights; public interface OnItemClickListener{
void onItemCLick(View view,int position);
void onItemLongClick(View view,int position);
} private OnItemClickListener mOnItemClickListener; public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener){
this.mOnItemClickListener = mOnItemClickListener;
} public WaterpallStaggeredAdapter(Context context,List<String> datas){
mInflater = LayoutInflater.from(context);
mDatas = datas; mHeights = new ArrayList<Integer>();
for (int i=0;i<mDatas.size();i++){
mHeights.add((int) (100 + Math.random() * 300));
}
} @Override
public MyViewHolder onCreateViewHolder(ViewGroup parrent, int viewType) {
MyViewHolder holder = new MyViewHolder(mInflater.inflate(R.layout.item_normal,parrent,false));
return holder;
} @Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
ViewGroup.LayoutParams lp = holder.tv.getLayoutParams();
lp.height = mHeights.get(position); holder.tv.setLayoutParams(lp);
holder.tv.setText(mDatas.get(position)); //如果设置了回调,则设置点击事件
if (mOnItemClickListener != null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onItemCLick(holder.itemView,pos);
}
}); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onItemLongClick(holder.itemView,pos);
removeData(pos);
return false;
}
});
} } @Override
public int getItemCount() {
return mDatas.size();
} public class MyViewHolder extends RecyclerView.ViewHolder { TextView tv; public MyViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.item_tx);
}
} public void removeData(int position){
mDatas.remove(position);
notifyDataSetChanged();
} }

这时候,在MainActivity中调用时时需要传入两个参数的,一个是context,一个是列表。

        mDatas = new ArrayList<String>();
mDatas.add("A");
mDatas.add("B");
mDatas.add("C");
mDatas.add("D");
mDatas.add("E");
mDatas.add("F");
mDatas.add("G");
mDatas.add("H");
mDatas.add("I");
mDatas.add("J");
mDatas.add("K");
mDatas.add("L");
mDatas.add("M");
mDatas.add("N");

至于那个LayoutManager有三种,可以自行尝试,会发现其中的区别的。其实上述列表如果想要简单一点,可以用一个For循环添加列表。。。

三、ItemDecoration添加分割线

使用方法:

为了使效果明显,可以修改下item.xml, 去掉CardView,改为LinearLayout,为其设置背景色,改变字体大小。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/cv_item"> <TextView
android:id="@+id/text_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:background="#ff0000"
android:textSize="28dp"
android:layout_gravity="center_horizontal"
android:text="TextView" /> </LinearLayout>

在MainActivity中加上分割线

recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));

效果图:

ItemDecoration很好的实现了RecyclerView添加分割线(当使用LayoutManager为LinearLayoutManager时)。该实现类可以看到通过读取系统主题中的Android.R.attr.listDivider作为Item间的分割线,并且支持横向和纵向。

该分割线是系统默认的,可以在theme.xml中找到该属性的使用情况。

在styles.xml找使用的android:listDivider的xml--shape_divider,也可以对其进行自定义。

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:listDivider">@drawable/ic_launcher_background</item>
</style>

下面给出DividerItemDecoration的代码:

package com.example.aimee.callbacktest;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View; public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
}; public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation; public DividerItemDecoration(Context context,int mOrientation){
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(mOrientation);
} public void setOrientation(int orientation){
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST){
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
} @Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST){
drawVertical(c,parent);
}else{
drawHorizontal(c,parent);
}
} public void drawVertical(Canvas c,RecyclerView parent){
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount();
for (int i=0;i<childCount;i++){
final View child = parent.getChildAt(i);
RecyclerView v = new RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
} public void drawHorizontal(Canvas c,RecyclerView parent){
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount();
for (int i=0;i<childCount;i++){
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
} @Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST){
outRect.set(0,0,0,mDivider.getIntrinsicHeight());
}else{
outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
}
}
}

接下来,怎么实现删除和添加的动画效果呢?如果是list<String>那么很简单,指需要.add和.remove就好了,但是如果是从string-array中读取的数据呢,它可没有.add方法,这时可以用到数据类型的转换。

当然我们这里不把list转换成array了,直接用list进行后面的操作。

MyAdapter.java

package com.example.aimee.recyclerviewtest;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private static final String TAG = "MyAdapter";
private final LayoutInflater mLayoutInflater;
private final Context mcontext;
private String[] mTitles;
private List<Integer> mHeights;
private List<String> mDatas; public MyAdapter(Context context){
mTitles = context.getResources().getStringArray(R.array.item_list);
mDatas = new ArrayList<>(Arrays.asList(mTitles));
mLayoutInflater = LayoutInflater.from(context);
mcontext = context;
mHeights = new ArrayList<Integer>(); for (int i=0;i<mTitles.length;i++){
mHeights.add((int) (100 + Math.random() * 300));
}
} @Override
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
return new ViewHolder(mLayoutInflater.inflate(R.layout.item_text,parent,false));
} @Override
public void onBindViewHolder(ViewHolder holder,int position){
ViewGroup.LayoutParams lp = holder.mTextView.getLayoutParams();
lp.height = mHeights.get(position); holder.mTextView.setLayoutParams(lp);
holder.mTextView.setText(mDatas.get(position));
} @Override
public int getItemCount(){
return mDatas == null?0:mDatas.size();
} public static class ViewHolder extends RecyclerView.ViewHolder { TextView mTextView; public ViewHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.text_item);
}
} public void addData(int position){
mDatas.add(position,"P");
mHeights.add((int) (100 + Math.random() * 300));
notifyDataSetChanged();
} public void removeData(int position){
mDatas.remove(position);
notifyDataSetChanged();
} }

还得添加一个menu菜单,使其可以添加,删除操作。

menu.xml

<?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/add"
android:title="添加"
app:showAsAction="always"/> <item
android:id="@+id/remove"
android:title="删除"
app:showAsAction="always"/> </menu>

然后在MainActivity中添加菜单函数

package com.example.aimee.recyclerviewtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem; public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MyAdapter myAdapter;
private int count=0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
myAdapter = new MyAdapter(this);
recyclerView.setAdapter(myAdapter);
recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
recyclerView.setItemAnimator(new DefaultItemAnimator());
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu,menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId(); if (id==R.id.add){
myAdapter.addData(count);
count = count + 2;
return true;
} if (id==R.id.remove){
if (count>=2)
count = count - 2;
myAdapter.removeData(count);
return true;
}
return super.onOptionsItemSelected(item);
}
}

效果图:

四、CardView的使用

第一个效果图就用了cardview,它可以拥有阴影个圆角。

  • 如果要使用阴影创建卡片,可使用card_view:cardElevation属性
  • 如果要在布局中设置圆角半径,可使用card_view.cardCornerRadius属性
  • 如果要在代码中设置圆角半径,可使用CardView.setRadius方法
  • 如果要设置卡片背景颜色,可使用card_view:cardBackgroundColor属性

参考博客:

https://blog.csdn.net/xx326664162/article/details/61199895

第三十九篇-RecyclerView的使用的更多相关文章

  1. Android UI开发第三十九篇——Tab界面实现汇总及比较

    Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,<Android UI开发第十八篇——ActivityGroup实现tab功能>.这 ...

  2. 第三十九篇 Python异常处理

    一. 什么是异常 异常就是程序运行时发生的错误,在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止,在python中,错误触发的异常如下 错误分成两种: #语法 ...

  3. C++第三十九篇 -- 研究一下Windows驱动开发(二)-- 驱动程序中重要的数据结构

    数据结构是计算机程序的核心,I/O管理器定义了一些数据结构,这些数据结构是编写驱动程序时所必须掌握的.驱动程序经常要创建和维护这些数据结构的实例. 一.驱动对象(DRIVER_OBJECT) 每个驱动 ...

  4. 第三十九篇:Vue3 watch(ref和reactive的监视)

    好家伙, 1.vue2中的watch是调用配置项,(只能写一个) vue3中的watch是一个函数(可以写很多个) 2.watch一些用法: 这里是定义的数据 set up(){ let sum =r ...

  5. 第三十九篇、NavBar动态隐藏、设置透明、毛玻璃效果

    1.动态隐藏 - (void)viewDidLoad { [super viewDidLoad]; if ([self respondsToSelector:@selector(automatical ...

  6. Python之路(第三十九篇)管道、进程间数据共享Manager

    一.管道 概念 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信. 先画一幅图帮助大家理解下管道的基本原理 现有2个 ...

  7. 第三十九篇 入门机器学习——Numpy.array的基础操作——合并与分割向量和矩阵

    No.1. 初始化状态 No.2. 合并多个向量为一个向量 No.3. 合并多个矩阵为一个矩阵 No.4. 借助vstack和hstack实现矩阵与向量的快速合并.或多个矩阵快速合并 No.5. 分割 ...

  8. 《手把手教你》系列技巧篇(三十九)-java+ selenium自动化测试-JavaScript的调用执行-上篇(详解教程)

    1.简介 在做web自动化时,有些情况selenium的api无法完成,需要通过第三方手段比如js来完成实现,比如去改变某些元素对象的属性或者进行一些特殊的操作,本文将来讲解怎样来调用JavaScri ...

  9. NeHe OpenGL教程 第三十九课:物理模拟

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

随机推荐

  1. 2019Java查漏补缺(一)

    看到一个总结的知识: 感觉很全面的知识梳理,自己在github上总结了计算机网络笔记就很累了,猜想思维导图的方式一定花费了作者很大的精力,特共享出来.原文:java基础思维导图 自己学习的查漏补缺如下 ...

  2. Centos7 安装Tomcat并运行程序

    运行环境:Centos7 jdk:1.8.0_171  Tocmcat:8.5.31 下载地址 :https://tomcat.apache.org/download-80.cgi#8.5.31 Ap ...

  3. mysql删除表中重复数据,只保留一个最小的id的记录

    语句: delete from table1 where id not in (select minid from (select min(id) as minid from table1 group ...

  4. wxPython的简单应用

  5. 第五节 matplotlib库

    一.Matplotlib基础知识 1.1Matplotlib中的基本图表包括的元素 x轴和y轴 axis水平和垂直的轴线 x轴和y轴刻度 tick刻度标示坐标轴的分隔,包括最小刻度和最大刻度 x轴和y ...

  6. How To Size Your Apache Flink® Cluster: A Back-of-the-Envelope Calculation

    January 11, 2018- Apache Flink Robert Metzger and Chris Ward A favorite session from Flink Forward B ...

  7. InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]'

    在新建asp.net core 应用后, 添加了自定义的ApplicationDbContext 和ApplicationUser ,并添加了Identity认证后, 会出现 InvalidOpera ...

  8. MYSQL primary key use btree 是什么含义了解一下

    CREATE TABLE `sth_definition` ( `id` int(11) NOT NULL AUTO_INCREMENT, `analyseId` bigint(20) DEFAULT ...

  9. python基础语法、数据结构、字符编码、文件处理 练习题

    考试范围 '''1.python入门:编程语言相关概念2.python基础语法:变量.运算符.流程控制3.数据结构:数字.字符串.列表.元组.字典.集合4.字符编码5.文件处理''' 考试内容 1.简 ...

  10. Linux+Shell常用命令总结

    因为自己不经常使用linux的命令行工具,但是mac的终端还是经常使用的,有些命令总是要想一会或者百度一下才知道怎么用,抽时间整理了一下常用的命令,作为笔记. 常用命令 查看文件操作: ls :列出当 ...