此文主要是将最近开发中遇到的一些小细节记录下来,主要涉及的是碎片和活动之间进行通讯android
一、问题一sql
extends AppCompatActivity android.support.v4.app.Fragment android.support.v4.app.DialogFragment;数据库
MainActivity ---------------> Fragment ---------------------------> DialogFragmentapp
具体应用: MainActivity --------------> MapFragment ------------------------> RouteDialogFragmentide
思路:其中主活动(MainActivity )采用BottomNavigationBar第三方类库来管理几个功能模块,采用Fragment来实现功能模块,包括(MapFragment ),而MapFragment 这个碎片因为进行路径规划起终点设置,因此使用RouteDialogFragment在MapFragment 基础上进行二次弹窗,截图以下:post
当设置完起终点位置后,点击“搜索”进行路径规划,最后将规划后的路径在MapFragment界面上显示。this
结构:spa
问题:怎样将规划后的路径在MapFragment界面上显示?指针
解决方案:一、MapFragment类中点击按钮,弹出RouteDialogFragment对话框,进行起终点设置;code
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;
二、在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; } }
三、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(内参本身定义) { //根据需求具体实现 }
四、在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 在页面销毁下的使用方式
二、问题二
从数据库遍历出来的数据表显示在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;
修改后效果: