一 接口回调机制在android中的应用十分广泛,比如button的点击事件,就用到的是接口回调,下面的代码为android中view的click方法:
/**
* view 的click事件
* Interface definition for a callback to be invoked when a view is clicked.
*/
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}
二 下面通过一个小程序,来了解下接口回调。
1.首先我们在这里创建了一个项目,InterfaceCallback,项目的目录结构如下:
2 首先,我们来讲解主界面的布局activity_main.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">
<TextView
android:gravity="center"
android:id="@+id/avtivity_title"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:text="activity_title_before(更换前)"
android:textSize="18sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ff0000"></View>
<fragment
android:id="@+id/fragment"
android:name="com.example.admin.interfacecallback.fragment.MyFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
tools:layout="@layout/my_fragment_layout"></fragment>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/reset_fragment_text"
android:layout_width="0dp"
android:layout_height="65dp"
android:layout_weight="1"
android:text="重置Fragment标题"
android:textSize="13sp" />
<Button
android:id="@+id/change_fragment_text"
android:layout_width="0dp"
android:layout_height="65dp"
android:layout_weight="1"
android:text="切换Fragment标题"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
如上,我们的主布局为Linearlayout,布局方式为垂直,在布局中有一个TextView为activity标题一个fragment标签,底部有两个按钮,分别为重置
Fragment标题和切换Fragment标题,(注:在这里我们仅仅只是想说明接口回调模式,其中的变化有很多种,有兴趣的朋友可以多多尝试)fragment
标签则表示的是Fragment的布局。其中引用fragment的布my_fragment_layout.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:orientation="vertical">
<TextView
android:id="@+id/fragment_title"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:text="fragment_title_before(更换前)"
android:textSize="18sp" />
<LinearLayout
android:layout_centerInParent="true"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_weight="1"
android:textSize="16sp"
android:text="重置activity标题"
android:id="@+id/reset_activity_title"
android:layout_width="0dp"
android:layout_height="60dp" />
<Button
android:layout_weight="1"
android:textSize="16sp"
android:text="切换activity标题"
android:id="@+id/change_activity_title"
android:layout_width="0dp"
android:layout_height="60dp" />
</LinearLayout>
</RelativeLayout>
我们可以看到在Fragment中的布局也是相对简单的,也是有一个TextView显示fragment标题两个Button用于切换和重置activity的标题。下面我们就通过详细的代码来讲解怎么实现接口回调.
3.下面我们来看看ActivityCallback接口,用于改变Fragment中标题的接口,代码如下:
package com.example.admin.interfacecallback.callback;
/**
* Created by admin on 2015/9/1.
*/
public interface ActivityCallback {
/**
* 这里用于改变fragment中的title,需要传入一个参数
* @param title 更改后的title名称
*/
void changeFragmentTitle(String title);
/**
* 重置Fragment标题
*/
void resetFragmentTitle(String title);
}
如上,这个方法在更改的时候需要传入一个参数为,你想要更改为的title名称。
4.再来看看FragmentCallback中的代码,同样只有一个方法,传入一个更改后的title名称即可,不说废话,看代码:
package com.example.admin.interfacecallback.callback;
/**
* Created by admin on 2015/9/1.
*/
public interface FragmentCallback {
/**
* 更改Activity中的title名称
* @param title 更改后的标题名称
*/
void changeActivityTitle(String title);
/**
* 重置Activity的标题
* @param title
*/
void resetActivityTitle(String title);
}
5.下面我们看看MyFragment中的代码,在代码中描述已经说的很清晰了,这里我也就不再解释,上代码:
package com.example.admin.interfacecallback.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.example.admin.interfacecallback.R;
import com.example.admin.interfacecallback.callback.ActivityCallback;
import com.example.admin.interfacecallback.callback.FragmentCallback;
/**
* Created by admin on 2015/9/1.
*/
public class MyFragment extends Fragment implements ActivityCallback{
/**
* 定义fragment的根布局View,用于初始化控件
*/
private View view;
/**
* Fragment的标题
*/
private TextView fragment_title;
/**
* 更改activity标题的按钮
*/
private Button change_activity_title,reset_activity_title;
/**
* activity中的点击回调
*/
private FragmentCallback callback;
/**
* 更换后的activity标题名称
*/
private String change_after_title = "change_title_after(更换后)";
/**
* 更换后的activity标题名称
*/
private String change_before_title = "change_title_before(更换前)";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 初始化回调接口
* 1.因为activity已经实现了FragmentCallback,所以他已经为FragmentCallback的子类,因此在这可以直接强转
*/
callback = (FragmentCallback) getActivity();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.my_fragment_layout,container,false);
/**
* 初始化界面
*/
init();
return view;
}
private void init() {
fragment_title = (TextView) view.findViewById(R.id.fragment_title);
change_activity_title = (Button) view.findViewById(R.id.change_activity_title);
change_activity_title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 判断非空
*/
if (callback != null)
{
callback.changeActivityTitle(change_after_title);
}
}
});
reset_activity_title = (Button) view.findViewById(R.id.reset_activity_title);
reset_activity_title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 判断非空
*/
if (callback != null)
{
callback.changeActivityTitle(change_before_title);
}
}
});
}
/**
* 当点击Activity中的切换按钮时的回调
* @param title 更改后的title名称
*/
@Override
public void changeFragmentTitle(String title) {
if (!TextUtils.isEmpty(title))
{
fragment_title.setText(title);
}
}
/**
* 用于还原最初的状态
* @param title
*/
@Override
public void resetFragmentTitle(String title) {
if (!TextUtils.isEmpty(title))
{
fragment_title.setText(title);
}
}
}
6.MainActivity中的代码,如下:
package com.example.admin.interfacecallback;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.admin.interfacecallback.callback.FragmentCallback;
import com.example.admin.interfacecallback.fragment.MyFragment;
public class MainActivity extends AppCompatActivity implements FragmentCallback{
/**
* activity的标题栏
*/
private TextView avtivity_title;
/**
* 界面引用fragment的实例
*/
private MyFragment fragment;
/**
* 更换fragment的标题title按钮
*/
private Button change_fragment_text,reset_fragment_text;
/**
* 更改过后的fragment标题名称
*/
private String change_after_title = "fragment_title_after(更换后)";
/**
* 更改过后的fragment标题名称
*/
private String change_before_title = "fragment_title_before(更换前)";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 初始化界面控件
*/
initView();
}
private void initView()
{
avtivity_title = (TextView) findViewById(R.id.avtivity_title);
change_fragment_text = (Button) findViewById(R.id.change_fragment_text);
fragment = (MyFragment) this.getFragmentManager().findFragmentById(R.id.fragment);
change_fragment_text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 判断非空
*/
if (fragment != null)
{
/**
* 因为MyFragment已经实现了ActivityCallback接口,所以这里可以直接使用
*/
fragment.changeFragmentTitle(change_after_title);
}
}
});
reset_fragment_text = (Button) findViewById(R.id.reset_fragment_text);
reset_fragment_text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 判断非空
*/
if (fragment != null)
{
/**
* 因为MyFragment已经实现了ActivityCallback接口,所以这里可以直接使用
*/
fragment.changeFragmentTitle(change_before_title);
}
}
});
}
/**
* 当点击Fragment中的切换按钮时的回调
* @param title 更改后的标题名称
*/
@Override
public void changeActivityTitle(String title) {
if(!TextUtils.isEmpty(title))
{
avtivity_title.setText(title);
}
}
/**
* 重置activity的title信息
* @param title
*/
@Override
public void resetActivityTitle(String title) {
if(!TextUtils.isEmpty(title))
{
avtivity_title.setText(title);
}
}
}
7.在这里我们主要核心,在于如下几句代码,
1.在MainActivty中获得MyFragment实例(这里我使用的是app包下的Fragment,若是你使用的是V4包下的Fragment那么你就需要让MainActivity实现FragmentActivity),以及将要更换的意图交给MyFragment类响应.
/**
* 界面引用fragment的实例
*/
private MyFragment fragment;
fragment = (MyFragment) this.getFragmentManager().findFragmentById(R.id.fragment);
/**
* 判断非空
*/
if (fragment != null)
{
/**
* 因为MyFragment已经实现了ActivityCallback接口,所以这里可以直接使用
*/
fragment.changeFragmentTitle(change_after_title);
}
/**
* 判断非空
*/
if (fragment != null)
{
/**
* 因为MyFragment已经实现了ActivityCallback接口,所以这里可以直接使用
*/
fragment.changeFragmentTitle(change_before_title);
}
2.在MyFragment中的onCreate方法中获取FragmentCallback对象(因为在这里MainActivity已经实现了FragmentCallback接口,所以该类已经为该接口子类,所以我在这里直接使用强转,若是你不明白,也可以在这里将声明的变量类型更换为MainActivity然后调用对应的接口方法也可以)。
/**
* activity中的点击回调
* 这里这个对象的类型可以声明成如下形式
* MainActicity callback
*/
private FragmentCallback callback;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 初始化回调接口
* 1.因为activity已经实现了FragmentCallback,所以他已经为FragmentCallback的子类,因此在这可以直接强转
* 2.当上面的变量类型声明为Mainactivity时,下面这句话可变为
* callback = (MainActivity)getActivity();
*/
callback = (FragmentCallback) getActivity();
}
多余的不在这里讲了,下面给大家看看最终的效果。
8.最终的效果演示如下:
9.到这里简单的就讲完了。其实也是很简单的,只要大家多多尝试,就会有很多比较细小的发现。
源码下载
链接为: http://download.csdn.net/detail/hxy_blog/9071151
欢迎大家纠正错误,如有问题可进行评论,谢谢。