碎片和活动间进行通信

来源:互联网 发布:java无难事 编辑:程序博客网 时间:2024/06/09 18:38

此文主要是将最近开发中遇到的一些小细节记录下来,主要涉及的是碎片和活动之间进行通信

1、问题一

extends  AppCompatActivity    android.support.v4.app.Fragment     android.support.v4.app.DialogFragment;

        MainActivity  --------------->  Fragment     --------------------------->     DialogFragment

具体应用:  MainActivity  -------------->  MapFragment ------------------------>    RouteDialogFragment

思路:其中主活动(MainActivity  )采用BottomNavigationBar第三方类库来管理几个功能模块,采用Fragment来实现功能模块,包括(MapFragment ),而MapFragment 这个碎片由于进行路径规划起终点设置,所以使用RouteDialogFragment在MapFragment 基础上进行二次弹窗,截图如下:

     

当设置完起终点位置后,点击“搜索”进行路径规划,最后将规划后的路径在MapFragment界面上显示。

结构:

问题:怎样将规划后的路径在MapFragment界面上显示?

解决方案:1、MapFragment类中点击按钮,弹出RouteDialogFragment对话框,进行起终点设置;

复制代码
case R.id.fab:                RouteDialogFragment dialogFragment = new RouteDialogFragment();                //设置target用于在dialogFragment中区分context是activity还是fragment 第二个参数为 requestCode 方便书写这里为0                dialogFragment.setTargetFragment(this,0);               //使用getChildFragmentManager()而不用getFragmentManager(),是因为DialogFragment是MapFragment的子碎片;               //MainActivity.ROUTE_DIALOG_TAG为RouteDialogFragment的TAG、                dialogFragment.show(getChildFragmentManager(),MainActivity.ROUTE_DIALOG_TAG) break;
复制代码

     2、在RouteDialogFragment类中采用接口回调的形式进行实现,接口定义(包括接口中的方法)在RouteDialogFragment类中;

复制代码
/**     * 定义该dialog需要的回调方法     */    public interface IConfirmDialogListener{        void setupSymbols(Point source, Point dest);    }//getDialogListener为辅助方法,简化每次都要强转的麻烦    private IConfirmDialogListener getConfirmDialogListener(){        return getDialogListener(IConfirmDialogListener.class);    }
复制代码

而其中getDialogListener(Class<T> listenerInterface)这个方法是定义在BaseDialogFragment(继承DialogFragment),此外RouteDialogFragment去继承这个BaseDialogFragment类,从而间接的继承了DialogFragment以及BaseDialogFragment类中的getDialogListener(Class<T> listenerInterface)这个方法。

BaseDialogFragment代码如下:

复制代码
import android.os.Bundle;import android.support.v4.app.DialogFragment;import android.support.v4.app.Fragment;/**DialogFragment基础类 * Created by Administrator on 2017/3/31. */public class BaseDialogFragment extends DialogFragment {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    /**     * 为获取接口类型定义的一个辅助方法 简化每次都要强转的麻烦     * @param listenerInterface     * @param <T>     * @return     */    protected <T> T getDialogListener(Class<T> listenerInterface) {        //用targetFragment是否为空来标识是fragment还是activity开启的这个DialogFragment        final Fragment targetFragment = getTargetFragment();        if (targetFragment != null && listenerInterface.isAssignableFrom(targetFragment.getClass())) {            return (T) targetFragment;        }        if (getActivity() != null && listenerInterface.isAssignableFrom(getActivity().getClass())) {            return ((T) getActivity());        }        return null;    }}
复制代码

                  3、MapFragment类中继承RouteDialogFragment类中定义的接口,同时实现接口中的方法。

public class MapFragment extends Fragment implements Toolbar.OnMenuItemClickListener, View.OnClickListener, RouteDialogFragment.IConfirmDialogListener {***********}  

在MapFragment类中实现接口中的方法,代码如下:

复制代码
 /**     * 设置开始、终点和路径图形符号     * Set up the Source, Destination and mRouteSymbol graphics symbol     */    @Override    public void setupSymbols(内参自己定义) {     //根据需求具体实现     }
复制代码

        4、在RouteDialogFragment类中通过接口对象调用接口中的方法。

复制代码
 } else if (p2 == null) {                Toast.makeText(getActivity(),                        "Not a valid destination address", Toast.LENGTH_LONG)                        .show();            } else            getConfirmDialogListener().setupSymbols(p1, p2);//执行后台服务            handler.post(new MyRunnable());//放在此处原因是避免出现空值情况,因为p1和p2还没有获取完的话就关闭对话框容易产生空指针异常        }
复制代码

 参考资料:

http://www.jianshu.com/p/5ba9f36a4a90         //Android DialogFragment 在页面销毁下的使用方式

 

2、问题二

从数据库遍历出来的数据表显示在listview上比较模糊,看不清,截图如下:

 

 

原因:Context对象不对,应该调用getActivity()。

错误方式如下:

复制代码
 ArrayList<String> arr = new ArrayList<String>();// 创建集合,用于存储字符串        SQLiteDatabase db = MyApplication.getContext().openOrCreateDatabase(dbName, Context.MODE_PRIVATE, null);// 创建或者打开数据库        Cursor cursor = db.rawQuery("select name from sqlite_master where (type='table') and (name<>'android_metadata') ", null);        while (cursor.moveToNext())// 遍历所有的植物信息        {            // 遍历出已存在于数据库中的表名            String name = cursor.getString(0);            arr.add(name);        }        cursor.close();        db.close();        arrayAdapter = new ArrayAdapter<String>(MyApplication.getContext(), android.R.layout.simple_list_item_1, arr);        this.aborOrHerb=aborOrHerb;
复制代码

正确方式如下:

复制代码
 ArrayList<String> arr = new ArrayList<String>();// 创建集合,用于存储字符串        SQLiteDatabase db = getActivity().openOrCreateDatabase(dbName, Context.MODE_PRIVATE, null);// 创建或者打开数据库        Cursor cursor = db.rawQuery("select name from sqlite_master where (type='table') and (name<>'android_metadata') ", null);        while (cursor.moveToNext())// 遍历所有的植物信息        {            // 遍历出已存在于数据库中的表名            String name = cursor.getString(0);            arr.add(name);        }        cursor.close();        db.close();        arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, arr);        this.aborOrHerb=aborOrHerb;
复制代码

修改后效果:

原创粉丝点击