TabLayout+ViewPager+Fragment+NDK+WebView+动画+自定义View+AIDL+xUtils+Fresco
一, 导入依赖 和 jar 包
compile 'com.jakewharton:butterknife:8.8.1' compile 'com.jakewharton:butterknife-compiler:8.8.1' compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.facebook.fresco:fresco:1.5.0' compile 'com.android.support:design:26.0.0-alpha1' compile 'com.android.support:support-v4:25.3.1'导入 xUtils.jar gson.jar
二, 主页面
1, 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="bw.com.bw1511a_month_test.MainActivity" android:orientation="vertical"> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="60dp" android:id="@+id/tab_layout_id"/> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/view_pager_id" /> </LinearLayout>
2, MainActivity.java
public class MainActivity extends AppCompatActivity { @BindView(R.id.tab_layout_id) TabLayout mTabLayout; private List<String> titles = new ArrayList<>();//标题 @BindView(R.id.view_pager_id) ViewPager mViewPager; private List<Fragment> data = new ArrayList<>();//数据源 private MyAdapter adapter; private Unbinder unbinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定ButterKnife unbinder = ButterKnife.bind(this); //初始化标题 titles.add("NDK"); titles.add("WebView"); titles.add("动画"); titles.add("自定义View"); titles.add("aidl"); titles.add("获取数据"); //构建数据源 data.add(new NdkFragment()); data.add(new WebViewFragment()); data.add(new AnimationFragment()); data.add(new CustomFragment()); data.add(new AidlFragment()); data.add(new DataFragment()); adapter = new MyAdapter(getSupportFragmentManager()); mViewPager.setAdapter(adapter); //tabLayout 和 ViewPager 结合 mTabLayout.setupWithViewPager(mViewPager); } class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return data.get(position); } @Override public int getCount() { return data.size(); } @Override public CharSequence getPageTitle(int position) { return titles.get(position); } } @Override protected void onDestroy() { super.onDestroy(); //解绑 unbinder.unbind(); } }
三, 第一个页面 --- NDK
环境配置路径: http://blog.****.net/xiuxiu_861223/article/details/78792939
页面: fragment_ndk.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.bw1511a_month_test.pager1.NdkFragment"> <!-- TODO: Update blank fragment layout --> <TextView android:id="@+id/tv_id" android:layout_width="match_parent" android:layout_height="match_parent" android:textColor="@color/colorAccent" android:textSize="30sp"/> </FrameLayout>
1, 定义 .java 的文件
public class JniTest { //TODO 后面出现so包后加入即可 static{ System.loadLibrary("app"); } //------------------------------- //声明native 修饰的方法 public static native String getStr(); // javah -d jni -classpath ../../build/intermediates/classes/debug bw.com.bw1511a_month_test.pager1.JniTest }2, make module "app" -- 生成.class 文件
3, 在studio 的控制台中, 输入 javah的指令 -- 生成 .h 文件
javah -d jni -classpath ../../build/intermediates/classes/debug bw.com.bw1511a_month_test.pager1.JniTest(修改红色的部分为自己的包+类)
4, 在.h 所在的文件夹中, 创建一个和.h 同名的 .c 文件
5, 在.c 的文件中, 写入内容
bw_com_bw1511a_month_test_pager1_JniTest.c
//导包 #include "bw_com_bw1511a_month_test_pager1_JniTest.h" JNIEXPORT jstring JNICALL Java_bw_com_bw1511a_1month_1test_pager1_JniTest_getStr (JNIEnv *env, jclass jclass) { return (*env)->NewStringUTF(env,"Hello AS!!!!!!"); }
6, make module "app" --- so包
PS:如果构建出现下面错误:
在gradle.properties文件中追加下面代码即可:
android.useDeprecatedNdk=true
7, 回到 .java 文件中, 通过静态代码块, 引入so 包
static{
System.loadLibrary("app");
}
8, 在Fragment方法中, 可以通过调用.java 中的方法, 去调用.c的内容
7, 回到 .java 文件中, 通过静态代码块, 引入so 包
static{
System.loadLibrary("app");
}
8, 在Fragment方法中, 可以通过调用.java 中的方法, 去调用.c的内容
/** * 通过ndk 获取C中返回的数据, 将获取的数据显示在TextView 中 */ public class NdkFragment extends Fragment { private Unbinder unbinder; @BindView(R.id.tv_id) TextView tv; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_ndk, container, false); //ButterKnife 初始化控件 unbinder = ButterKnife.bind(this,view); String str = JniTest.getStr(); tv.setText(str); return view; } @Override public void onDestroyView() { super.onDestroyView(); //解绑 unbinder.unbind(); } }
四, 第二个页面 --- WebView
1, 页面 fragment_web_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="bw.com.bw1511a_month_test.pager2.WebViewFragment"> <ProgressBar android:layout_width="match_parent" android:layout_height="10dp" android:id="@+id/pb_id" style="?android:attr/progressBarStyleHorizontal" /> <!-- TODO: Update blank fragment layout --> <WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/web_view_id"/> </LinearLayout>
2, WebViewFragment.java
/** * WebView -- 显示网页 */ public class WebViewFragment extends Fragment { private Unbinder unbinder; @BindView(R.id.web_view_id) WebView webView; @BindView(R.id.pb_id) ProgressBar progressBar; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_web_view, container, false); //ButterKnife的绑定 unbinder = ButterKnife.bind(this,view); //加载地址 webView.loadUrl("http://www.baidu.com"); //设置支持js webView.getSettings().setJavaScriptEnabled(true); //在当前的页面中打开网页 webView.setWebViewClient(new WebViewClient(){ //todo 重定向地址 @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { webView.loadUrl("http://www.baidu.com"); // 在Fragment 中, 建议在此处重定向地址 return super.shouldOverrideUrlLoading(view, request); } //todo 页面加载开始 -- 进度条显示 @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); if(progressBar!=null) { progressBar.setVisibility(View.VISIBLE); } } //todo 页面加载完成 -- 进度条消失 @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if(progressBar!=null) progressBar.setVisibility(View.GONE); } }); //如果需要和页面中的内容交互 -- 显示加载的进度, 显示页面中的alert 信息 webView.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); //TODO 设置进度值 if(progressBar!=null) { progressBar.setProgress(newProgress); } } }); return view; } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind();//解绑 } }
五, 第三个页面 -- 动画 -- 补间动画-- 实现 渐变, 缩放, 旋转, 位移, 集合的效果
1, fragment_animaction.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="bw.com.bw1511a_month_test.pager3.AnimationFragment"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/but_01" android:text="渐变"/> <Button android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/but_02" android:text="缩放"/> <Button android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/but_03" android:text="旋转"/> <Button android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/but_04" android:text="位移"/> <Button android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/but_05" android:text="集合"/> </LinearLayout> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:layout_gravity="center" android:id="@+id/iv_id"/> </LinearLayout>
2, AnimationFragment.java
/** * 通过动画, 实现 渐变, 缩放, 旋转, 位移, 结合的效果 * */ public class AnimationFragment extends Fragment implements View.OnClickListener { private Unbinder unbinder; @BindView(R.id.iv_id) ImageView iv; @BindView(R.id.but_01) Button but01; @BindView(R.id.but_02) Button but02; @BindView(R.id.but_03) Button but03; @BindView(R.id.but_04) Button but04; @BindView(R.id.but_05) Button but05; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_animation, container, false); unbinder = ButterKnife.bind(this,view); but01.setOnClickListener(this); but02.setOnClickListener(this); but03.setOnClickListener(this); but04.setOnClickListener(this); but05.setOnClickListener(this); return view; } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.but_01: //渐变 AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.0f); alphaAnimation.setDuration(3000);//设置持续时间 //translateAnimation.setFillAfter(true); iv.startAnimation(alphaAnimation);//启动动画 break; case R.id.but_02: //缩放 //ScaleAnimation scaleAnimation = new ScaleAnimation(1f,3f,1f,3f);//左上角 ScaleAnimation scaleAnimation = new ScaleAnimation(1f,3f,1f,3f, Animation.RELATIVE_TO_SELF,0.5f,//X轴的一半 Animation.RELATIVE_TO_SELF,0.5f);//Y轴的一半 scaleAnimation.setDuration(3000); iv.startAnimation(scaleAnimation); break; case R.id.but_03: //旋转 // RotateAnimation rotateAnimation = new RotateAnimation(0,720);左上角 RotateAnimation rotateAnimation = new RotateAnimation(0,720, Animation.RELATIVE_TO_SELF,0.5f,//X轴的一半 Animation.RELATIVE_TO_SELF,0.5f);//Y轴的一半 rotateAnimation.setDuration(3000); iv.startAnimation(rotateAnimation); break; case R.id.but_04: //位移 TranslateAnimation translateAnimation = new TranslateAnimation(0,500,0,600); translateAnimation.setDuration(3000); //translateAnimation.setFillAfter(true); iv.startAnimation(translateAnimation); break; case R.id.but_05: //集合 AnimationSet animationSet = new AnimationSet(false); AlphaAnimation aAnimation = new AlphaAnimation(1.0f,0.0f); TranslateAnimation tAnimation = new TranslateAnimation(0,800,0,800); animationSet.addAnimation(aAnimation); animationSet.addAnimation(tAnimation); animationSet.setDuration(3000); iv.startAnimation(animationSet); break; } } }
六, 第四个页面 -- 自定义View ---实现柱状图 + 扇形
1, 页面 fragment_custom.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.bw1511a_month_test.pager4.CustomFragment"> <!-- TODO: Update blank fragment layout --> <bw.com.bw1511a_month_test.pager4.CustomView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/cs_id"/> </FrameLayout>
2, CustomView.java
/** * 柱状图 */ public class CustomView extends View{ private Paint paint;//画笔 private int rect_width = 30;//柱子的宽度 private int rect_space = 20;//柱子之间的间隔 private int[][] rects = {{Color.RED,300},{Color.GREEN,400},{Color.BLUE,500},{Color.YELLOW,600}}; public CustomView(Context context) { super(context); } public CustomView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(); paint.setStrokeWidth(5);//设置画笔的粗细 paint.setAntiAlias(true);//设置抗锯齿 paint.setColor(Color.BLACK); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制300 canvas.drawText("300",10,getHeight()-350,paint); //绘制300 对应的 圆 canvas.drawCircle(50,getHeight()-350,5,paint); //绘制柱子 -- 循环 for(int i = 0;i<rects.length;i++) { paint.setColor(rects[i][0]);//设置画笔的颜色 int left = 50 +rect_space +(rect_space+rect_width)*i; int top = getHeight()-rects[i][1]-50; canvas.drawRect(left,top,left+rect_width,getHeight()-50,paint); } paint.setColor(Color.BLACK); //绘制X轴 canvas.drawLine(50,getHeight()-50,getWidth()-50,getHeight()-50,paint); canvas.drawLine(getWidth()-50,getHeight()-50,getWidth()-75,getHeight()-75,paint); canvas.drawLine(getWidth()-50,getHeight()-50,getWidth()-75,getHeight()-25,paint); //绘制Y轴 canvas.drawLine(50,50,50,getHeight()-50,paint); canvas.drawLine(50,50,25,75,paint); canvas.drawLine(50,50,75,75,paint); //绘制XY交汇处 canvas.drawCircle(50,getHeight()-50,5,paint); //绘制扇形 paint.setColor(Color.RED); RectF rectF = new RectF(500,500,900,900); canvas.drawArc(rectF,0,160,true,paint); } }
七, 第五个页面 -- AIDL -- 读取服务器中的数据库内容
需要 服务端 + 客户端
服务端:
1, 在src/main 目录中创建.aidl 文件
DataAidl.aidl
interface DataAidl { String getDbInfo(); }
2, 编译工程 -- 生成DataAidl.java文件
3, 数据库的创建 -- DbOpenHelper.java
/** * 数据库的帮助类 * */ public class DbOpenHelper extends SQLiteOpenHelper{ public DbOpenHelper(Context context) { super(context, "bw1511A.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table if not exists user(_id integer primary key autoincrement,uName,uPwd)"); db.execSQL("insert into user(uName,uPwd) values('abc','123')"); db.execSQL("insert into user(uName,uPwd) values('bcd','222')"); db.execSQL("insert into user(uName,uPwd) values('def','123')"); db.execSQL("insert into user(uName,uPwd) values('eee','234')"); db.execSQL("insert into user(uName,uPwd) values('tre','444')"); db.execSQL("insert into user(uName,uPwd) values('yui','123')"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
4, 创建服务 MyService.java
public class MyService extends Service { DataAidl.Stub stub = new DataAidl.Stub() { @Override public String getDbInfo() throws RemoteException { //获取数据库中的所有内容, 并且返回 DbOpenHelper dbOpenHelper = new DbOpenHelper(getApplicationContext()); SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from user",null); StringBuilder sBuilder = new StringBuilder(); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("uName")); String pwd = cursor.getString(cursor.getColumnIndex("uPwd")); sBuilder.append("姓名: " + name).append(", 密码: "+pwd).append("\n"); } Log.e("TAG","--" + sBuilder.toString()); return sBuilder.toString();
//不要忘记了Service 的注册啊
} }; @Nullable @Override public IBinder onBind(Intent intent) { return stub; }}5, 注册Service
<!--注册Service--> <service android:name=".MyService"> <intent-filter> <action android:name="com.bw.aidl"/> </intent-filter> </service>
客户端
1, 将服务器端的aidl 文件夹, 不做任何修改, 复制到 客户端的 src/mian 目录中
2, 编译工程 -- 生成DataAidl.java文件
3, AidlFragment.java
/** * 客户端 -- 服务器端 获取数据库中所有内容 *客户端: * 绑定服务 * 在绑定成功的回调方法中,得到 .ava 对象 * 可以根据对象, 调用方法 * */ public class AidlFragment extends Fragment { private Unbinder unbinder; @BindView(R.id.tv_id) TextView tv; //检测服务是否绑定成功 private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { try { //获取aidl 对应的.java 文件 DataAidl dataAidl = DataAidl.Stub.asInterface(service); String str = dataAidl.getDbInfo(); tv.setText(str); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_aidl, container, false); //绑定 unbinder = ButterKnife.bind(this,view); return view; } //todo 绑定服务 @Override public void onResume() { super.onResume(); Intent intent = new Intent("com.bw.aidl"); intent.setPackage("bw.com.server");//5.0 后必须加--服务器的包名一致 getContext().bindService(intent,connection, Context.BIND_AUTO_CREATE); } //todo 解绑服务 @Override public void onPause() { super.onPause(); getContext().unbindService(connection); } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind();//解绑 } }4, 页面 -- fragment_aidl.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.bw1511a_month_test.pager5.AidlFragment"> <!-- TODO: Update blank fragment layout --> <TextView android:id="@+id/tv_id" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_blank_fragment" /> </FrameLayout>
八, 网络获取数据 -- xUtils获取数据, 展示到RecycleView 中, 图片获取用Fresco
1, 创建MyApp.java
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); //初始化 x.Ext.init(this); x.Ext.setDebug(true); Fresco.initialize(this); } }
2, 在清单文件中引入
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:name=".MyApp" android:allowBackup="true"
3, DataFagment.java
/** * 通过网络请求框架 获取网络数据 -- xUtils -- 初始化 * 通过Fresco 获取网络图片 -- 初始化 * 点击每个条目, 弹出AlertDialog, 显示选中的内容 */ public class DataFragment extends Fragment { private Unbinder unbinder; @BindView(R.id.rv_id) RecyclerView recyclerView; @Override public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_data, container, false); unbinder = ButterKnife.bind(this,view); //设置显示的模式 recyclerView.setLayoutManager(new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false)); //为RecycleView 设置动画 //获取网络数据 -- 设置适配器 RequestParams params = new RequestParams("http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1"); x.http().get(params, new Callback.CommonCallback<String>() { @Override public void onSuccess(String s) { //解析得到数据源 CookBook cookBook = new Gson().fromJson(s,CookBook.class); final List<CookBook.DataBean> data = cookBook.getData(); //适配器 MyRecycleViewAdapter adapter = new MyRecycleViewAdapter(getContext(),data); recyclerView.setAdapter(adapter); //TODO --1-- 为RecycleView 设置监听器 adapter.setOnItemClickListener(new MyRecycleViewAdapter.OnItemClickListener() { @Override public void onClick(int position) { //自定义对话框, 显示详细信息 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); //加载页面 View dialogView = LayoutInflater.from(getContext()).inflate(R.layout.dialog_view,null); //加载控件 SimpleDraweeView sdv = (SimpleDraweeView) dialogView.findViewById(R.id.sdv_id); TextView tv = (TextView) dialogView.findViewById(R.id.tv_id); //设置内容 sdv.setImageURI(Uri.parse(data.get(position).getPic())); tv.setText(data.get(position).getTitle()); //设置显示的页面 builder.setView(dialogView); //显示对话框 builder.show(); } @Override public void onLongClick(int position) { } }); } @Override public void onError(Throwable throwable, boolean b) { } @Override public void onCancelled(CancelledException e) { } @Override public void onFinished() { } }); return view; } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); } }4, 页面 fragment_data.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.bw1511a_month_test.pager6.DataFragment"> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/rv_id" /> </FrameLayout>5, 页面 item_rv.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.facebook.drawee.view.SimpleDraweeView android:layout_width="200dp" android:layout_height="200dp" android:id="@+id/sdv_id" fresco:placeholderImage="@mipmap/ic_launcher" fresco:roundedCornerRadius="10dp" fresco:roundTopLeft="true" fresco:roundTopRight="true" fresco:roundBottomLeft="true" fresco:roundBottomRight="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题" android:id="@+id/title_id" android:textSize="20sp" android:layout_marginTop="10dp"/> </LinearLayout>6, dialog_view.xml -- 点击条目弹出的对话框
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco ="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:padding="20dp"> <com.facebook.drawee.view.SimpleDraweeView android:layout_width="200dp" android:layout_height="200dp" fresco:placeholderImage="@mipmap/ic_launcher" android:id="@+id/sdv_id"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_id" android:text="标题" android:textSize="20sp" /> </LinearLayout>7, MyRecycleViewAdapter.java
public class MyRecycleViewAdapter extends RecyclerView.Adapter<MyRecycleViewAdapter.ViewHolder> { private OnItemClickListener mOnItemClickListener;//TODO 为RecycleView 设置监听器 private Context context; private List<CookBook.DataBean> data; public MyRecycleViewAdapter(Context context,List<CookBook.DataBean> data) { this.context = context; this.data = data; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_rv,parent,false); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(ViewHolder holder, final int position) { Uri uri = Uri.parse(data.get(position).getPic()); holder.sdv.setImageURI(uri); holder.title.setText(data.get(position).getTitle()); //TODO --1-- 为RecycleView 设置监听器 if( mOnItemClickListener!= null){ holder.itemView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onClick(position); } }); holder. itemView.setOnLongClickListener( new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mOnItemClickListener.onLongClick(position); return false; } }); } } @Override public int getItemCount() { return data.size(); } class ViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.sdv_id) SimpleDraweeView sdv; @BindView(R.id.title_id) TextView title; public ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this,itemView); } } //TODO --1-- 为RecycleView 设置监听器 --- 自定义接口 public interface OnItemClickListener{ void onClick( int position); void onLongClick( int position); } //TODO --1-- 向外提供公共的方法 public void setOnItemClickListener(OnItemClickListener onItemClickListener ){ this. mOnItemClickListener=onItemClickListener; } }8, CookBook.java - - GsonFormant 生成的实体类