通过 回调让Activity和Fragment及时交互

本文探讨了如何通过回调方式使Activity和Fragment能够及时交互。通过一个银行短信服务的类比解释了回调的概念,并提供了一个简单的例子,展示了在选择城市列表的Fragment中,当用户选择城市时,如何通过回调将信息传递给Activity更新标题。示例代码包括Activity布局和逻辑,以及Fragment的交互实现。
摘要由CSDN通过智能技术生成

Fragment 一经推出,就广泛的使用在项目中,在适配方面,减少代码冗余方面大有助益,那么Fragment和Activity如何交互呢,我所知的有,通过fragment.setxxx(),((类型转换)getActivity).setxxx(),eventbus等等,那么是否可以通过回调让Activity和 Fragment及时交互呢?

首先讲一下我对回调的理解,A要完成某件事情,但是他没法完成,需要委托B去完成,B完成了告诉A完成的情况。

举一个列子,在办理银行卡的时候,有时候会开通短信服务,当你的银行卡中钱发生变化的时候 就会及时通知你,这就相当会 客户给银行设置了一个监听,这个监听一直在等待,钱有变化了 就回调出结果,如果你不设置监听,钱变化了,自然也不会及时通知你

写一个简单的例子:

MoneyCallBack 作为一个接口,主要用于监听银行卡中钱的变化,相当于定制的短信服务

package callbackDemo;

/**
 * @author why 小二
 * 短信业务
 *
 */
public interface MoneyCallBack {
	void savaMoney();//短信通知用户存钱了
	void spendMoney();//短信通知用户消费了

}
Bank 作为一个银行类主要用于处理存钱,取钱 啥啥啥的金融业务,当用户的钱发生 变化时,如果用户办理了短信服务,通知用户钱发生了变化,这里的短信服务相当于上面的MoneyCallBack,如果不设置,当然也就不通知了

package callbackDemo;

/**
 * @author why
 * 银行
 *
 */
public class Bank {
	MoneyCallBack mCallBack;
	int mMonthCount=12;// 办理短信服务的月数,一般为12个月
	
	public void setCallBack(MoneyCallBack mCallBack) {
		this.mCallBack = mCallBack;
	}
	public void getMoney(){
		new Thread(){public void run() {
			for (int i = 0; i < mMonthCount; i++) {
				if (mCallBack!=null) {
					mCallBack.savaMoney();
					mCallBack.spendMoney();
					
				}
				
			}
		};
		}.start();
	}

}

Client作为 办理银行业务的自由人,可以办理任何业务

package callbackDemo;

/**
 * @author why 小二
 * 客户
 *
 */
public class Client {
	public static void main(String[] args) {
		Bank bank=new Bank();
		//定制短信服务 
		bank.setCallBack(new MoneyCallBack() {
			
			@Override
			public void spendMoney() {
				System.out.println("尊敬的客户,你存入了钱");
				
			}
			
			@Override
			public void savaMoney() {
				System.out.println("尊敬的客户,你消费了钱");
				
			}
		});
		
		bank.getMoney();
		
	}

}

好了,现在执行下 程序,12个月中有存钱,有消费




如果你想知道 消费 收入的具体变化,只需在回调接口中返回具体的数目,把接口稍作修改

package callbackDemo;

/**
 * @author why 小二
 * 短信业务
 *
 */
public interface MoneyCallBack {
	void savaMoney(String money);//短信通知用户存钱了
	void spendMoney(String money);//短信通知用户消费了

}

总之回调很简单,你可以通过任何方式给B设计监听,构造函数,set等等,只要设置了,B就可以通过接口返回,现在通过一个 Activity和 Fragment的例子讲解,写一个非常简单的,Fragment中是一个城市列表,用于选择一个城市,Activity 用大标题显示出来当前选择的城市是哪个城市,adapter点击发生变化了通过 回调返回给Fragment,Fragment 再回调给 Activity

先看下效果




右边的单选是随意找的两张图片,有点丑,效果是非常好的,但是我录制的不好就这个丑样子了

现在贴代码


先看下 Activity 布局 ,只有一个TextView 和LinearLayout ,用于展示当前城市的名字 和 添加Fragment。

<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:id="@+id/title" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25dp"/>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment_content"></LinearLayout>

</LinearLayout>

Activity 代码

package com.example.why.callbackinteraction;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.TextView;


/**
 * Created by why on 2015/9/6.
 */
public class MainActivity extends Activity {
    private TextView mTitleView;
    private FragmentManager manager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitleView= (TextView) findViewById(R.id.title);
        mTitleView.setText("你当前选择的城市是 ");
        manager=getFragmentManager();
        FragmentTransaction transaction=manager.beginTransaction();
        CityChoiceFragment fragment=new CityChoiceFragment();
        //Fragment 实例化 之后设置,设置了 ,Fragment 选择城市发生改变返回给 Activity
        fragment.setmFragmentCallBack(new CityChoiceFragment.FragmentCallBack() {
            @Override
            public void getCity(String cityName) {
                mTitleView.setText(String.format("你当前选择的城市是   %s",cityName));
            }
        });
        transaction.add(R.id.fragment_content,fragment);
        transaction.commitAllowingStateLoss();

    }
}
很简单,我就不解释了,下面是 Fragment 和 Adapter的代码,布局很简单,不上了,代码不解释了,代码中有注释

package com.example.why.callbackinteraction;

import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by why on 2015/9/5.
 */
public class CityChoiceFragment extends Fragment {
    private ListView mCityListView;
    private List<String> mCitys; //城市列表
    CityAdapter mAdapter;

    public void setmFragmentCallBack(FragmentCallBack mFragmentCallBack) {
        this.mFragmentCallBack = mFragmentCallBack;
    }
<span style="white-space:pre">	</span>
    private FragmentCallBack mFragmentCallBack;//用于把内容回调给Activity
    interface  FragmentCallBack{
        void getCity(String cityName);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.fragment_city_choice,null);
        initDate();
        initView(view);
        return view;
    }

    /**
     * @param view
     */
    private void initView(View view) {
        mCityListView= (ListView) view.findViewById(R.id.city_list);
        mAdapter=new CityAdapter(mCitys,getActivity());
        // 为adapter设置接口,如果设置了,adapter有所改变 ,将会把改变的的城市返回,接口可以在实例化或实例化后位置设置,
        mAdapter.setmChoiceChangeCallBack(new CityAdapter.ChoiceChangeCallBack() {
            @Override
            public void getSelectCity(String cityName) {
                if (mFragmentCallBack!=null){
                    mFragmentCallBack.getCity(cityName);
                }

            }
        });
        mCityListView.setAdapter(mAdapter);

    }

    /**
     * 初始化数据
     */
    private void initDate() {
        mCitys=new ArrayList<>();
        mCitys.add("博乐");
        mCitys.add("伊宁");
        mCitys.add("阿拉山口");
        mCitys.add("霍尔果斯");
        mCitys.add("奎屯");
        mCitys.add("石河子");
        mCitys.add("乌鲁木齐");
        mCitys.add("哈密");
        mCitys.add("吐鲁番");
        mCitys.add("库尔勒");
        mCitys.add("鄯善");
        mCitys.add("北屯");
        mCitys.add("和田");
        mCitys.add("昌吉");
        mCitys.add("塔城");
        mCitys.add("克拉玛依");
        mCitys.add("阿图什");
        mCitys.add("阿克苏");

    }
}

class CityAdapter extends BaseAdapter{
    interface ChoiceChangeCallBack{
        void  getSelectCity(String cityName);

    }

    public void setmChoiceChangeCallBack(ChoiceChangeCallBack mChoiceChangeCallBack) {
        this.mChoiceChangeCallBack = mChoiceChangeCallBack;
    }

    private  ChoiceChangeCallBack mChoiceChangeCallBack;  //当前点击item的回调接口,如果点击了,通过接口把选择的城市返回给 fragment
    private List<String> mCitys;
    private Context mContext;
    private LayoutInflater mInflater;
    private String mCurrentCity="";

    CityAdapter(List<String> mCitys, Context mContext) {
        this.mCitys = mCitys;
        this.mContext = mContext;
        mInflater=LayoutInflater.from(mContext);
    }

    @Override
    public int getCount() {
        return mCitys==null?0:mCitys.size();
    }

    @Override
    public Object getItem(int position) {
        return mCitys==null?null:mCitys.get(position);
    }
    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
      ViewHodler hodler;
        if (convertView==null){
            hodler=new ViewHodler();
            convertView=mInflater.inflate(R.layout.adapter_city_choice,null);
            hodler.name= (TextView) convertView.findViewById(R.id.name);
            hodler.choice= (TextView) convertView.findViewById(R.id.choice);
            convertView.setTag(hodler);
        }else{
            hodler= (ViewHodler) convertView.getTag();
        }
        hodler.name.setText(mCitys.get(position));
        hodler.choice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCurrentCity=mCitys.get(position);
                v.setBackgroundResource(R.drawable.sure);
                if (mChoiceChangeCallBack!=null){
                    mChoiceChangeCallBack.getSelectCity(mCurrentCity);
                }
                notifyDataSetChanged();


            }
        });
        if (mCurrentCity.equals(mCitys.get(position))){
            hodler.choice.setBackgroundResource(R.drawable.sure);
        }else {
            hodler.choice.setBackgroundResource(R.drawable.add);
        }

        return convertView;
    }

    class ViewHodler{
        TextView name;
        TextView choice;
    }
}




module下载地址 ,请点击 这里


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值