对于刚接触接口的我来讲,真的是好难的一个东西啊,感觉不断在追着数据跑,照着例子敲 有时还不知道敲的是什么,上网上找博客看 有个例子是打电话,那个让我大概了解了接口,但是对于怎么写一个接口传值仍一头雾水.不过什么东西敲多了就大概了解了.
我们用接口来传值的一个很典型的例子就是RecyclerView的点击事件.所以我们来分析一下点击事件的书写顺序:
首先我们需要建立一个接口,如同建立一个类一样,不过把class换为interface 接口名字其实可以随便取(刚开始学时候以为名字改了不能用呢) 不过最好可以看出为RecyClerView的接口, 在接口里写一个没有方法体的方法,类似这个 ,我希望传的是点击的位置,也可以传递其他参数
public interface OnRecItemClickListener {
public void onRecclick(int position);
}
建立完接口我们需要找到你想在什么界面或什么情况下触发这个接口,比如这个RecyclerView 我希望在它的行布局被点击时候触发,那么我需要找在哪里有它的行布局,是RecyclerView的适配器在onBindViewHolder中我们看到他在对行布局的视图进行操作,那么我们就在这里触发接口
既然知道在那个界面有着接口的触发条件,首先我们需要在这个界面创建一个接口对象
private OnRecyclerItemClick onRecyclerItemClick;
这个接口对象需要一个赋值方法,不然会空指针(在适配器中用这个方法,假如在Fragment中想向Activity传值需要Activity implement接口 在Fragment中用onAttach赋给接口对象值 如下 [只有依附在该activity上的fragment可以向activity传值,若是两者没有关系,不要使用接口回调 ])
public void setOnRecyclerItemClick(OnRecyclerItemClick onRecyclerItemClick) {
this.onRecyclerItemClick = onRecyclerItemClick;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context=context;
operateDatabase= (OperateDatabase) context;
}
在我们有了一个不为空的接口对象后,我们需要在行布局被点击的事件中(系统的)来触发我们自己写的 如下 ,在onBindViewHolder 中
holder1.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onRecyclerItemClick.onItemClick(position);
}
});
如上,在holder中或的行布局视图itemview ,在itemView点击时 触发行布局点击并且传值,不过这时候我们还没有能接收对象的
不过接下来就很简单了,我们只需要像使用其它接口时使用就行,不过因为是在adapter中触发此事件,我们需要用adapter.setOnReclerItemClick(this),而不是像listview的点击是listview.setOnitemClickListener 这是我们就可以操作了,我们操作的就是传过来的position.其他接口回调的使用方法是一样的
我们只需要找到我们想传什么,从什么界面传,传到那个界面,以及在什么情况下传 接口回调使用就不难.
就比如我们在MainActivity的ViewPager中的Fragment向MainActivity传值 (也不一定是传值,有时我们在fragment做了某些操作,然后希望Activity做一些操作,我们也是用接口)
比如说我在fragment中有对数据库进行操作的按钮,但是操作过程我们希望在MainActivity中进行,首先我们的接口(与之前的类似):
public interface OperateDatabase {
void insert();
void deltete();
void query();
void update();
}
数据库的四种操作,在Fragment中我们还是先定义接口对象
private OperateDatabase operateDatabase;
然后我们初始化它,代码如下(context是Activity,因为Activity implement了这个接口,所以可以转换)
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context=context;
operateDatabase= (OperateDatabase) context;
}
接着我们开始找什么时候触发接口,让Activity中的insert 方法执行,我们在点击按钮时执行,所以我们写按钮的点击事件,并调用接口中方法
@Override
public void onClick(View view) {
switch (view.getId())
{
case R.id.add_btn:
operateDatabase.insert();
break;
case R.id.update_btn:
operateDatabase.update();
break;
case R.id.delete_btn:
operateDatabase.deltete();
break;
case R.id.query_btn:
operateDatabase.query();
break;
}
}
而这个时候,我们在fragment中的操作就结束了,我们需要到Activity中进行操作
首先我们implement接口
public class MainActivity extends BaseActivity implements OperateDatabase{
这时就需要如同onClick时间一样,实现方法(这个方法的名字是我们自己起的) 并且在方法中实现我们在Fragment点击按钮后需要Activity做的事情
在这里我之前已经建立了数据库和表,这里就进行了对数据库的操作
@Override
public void insert() {
ContentValues values=new ContentValues();
values.put("name","value");
db.insert("student",null,values);
Log.e("66666", "insert: ");
}
@Override
public void deltete() {
db.delete("student","name=?",new String[]{"values"});
Log.e("66666", "delete: ");
}
@Override
public void query() {
Cursor cursor =db.query("student",null,null,null,null,null,null);
if (cursor!=null) {
while (cursor.moveToNext()) {
String name=cursor.getString(cursor.getColumnIndex("name"));
}
}
Log.e("66666", "query: ");
}
@Override
public void update() {
ContentValues values=new ContentValues();
values.put("name","update");
db.update("student",values,"name=?",new String[]{"value"});
Log.e("66666", "update: ");
}
这样fragment向Activity传值就实现了,需要传值就在我们定义接口时写进去,在传值时传过去就好.我的这个例子没有传值,以下是我随便点打的log
E/66666: insert:
E/66666: delete:
E/66666: update:
E/66666: query:
E/66666: insert:
E/66666: insert:
不过因为我是个初学者,对于原理什么的都不懂,所以上述所有肯定会有错误,so小心踩雷.