碎片和活动间进行通信

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

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;

修改后效果:

原文地址:https://www.cnblogs.com/gis-laozhang/p/6650931.html