碎片和活動間進行通訊

 

此文主要是將最近開發中遇到的一些小細節記錄下來,主要涉及的是碎片和活動之間進行通訊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;

修改後效果:

相關文章
相關標籤/搜索