2013-11-28 3 views
0
안드로이드

에서 DialogFragment에서 :CustomDialog 나는이 같은 대화 상자 (구글지도 계층 대화 선택) 구축을 위해 노력하고

enter image description here

을 그리고 이것은 내 핵심 코드이다 :

public class MapLayerSourceChooseDialog extends DialogFragment { 
    private MapLayerSelectedListener mListener; 
    private LayerAdapter mLayerAdapter; 

    public void setLayerSelectListener(MapLayerSelectedListener listener) { 
     mListener = listener; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mLayerAdapter = new LayerAdapter(getActivity(), R.layout.common_dialog_maplayer, new ArrayList<MapLayer>()); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     builder.setTitle("Layers").setAdapter(mLayerAdapter, new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 

       if (mListener != null) { 
        MapLayer layer = mLayerAdapter.getItem(which); 
        mListener.OnMapLayerSelected(which, layer); 
       } 
      } 
     }); 
     Log.d("map", "dialog on create"); 
     return builder.create(); 
    } 

    public void updateData(List<MapLayer> layers) { 
     mLayerAdapter.updateItems(layers); 
    } 

    private class LayerAdapter extends ArrayAdapter<MapLayer> { 
     private List<MapLayer> mItems; 

     public LayerAdapter(Context context, int resource, List<MapLayer> items) { 
      super(context, resource, items); 
      mItems = items; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      ViewHolder holder = null; 
      if (convertView == null || convertView.getTag() == null) { 
       convertView = getActivity().getLayoutInflater().inflate(R.layout.common_dialog_maplayer, parent, false); 

       holder = new ViewHolder(); 
       holder.iconView = (ImageView) convertView.findViewById(R.id.map_layer_icon); 
       holder.nameView = (TextView) convertView.findViewById(R.id.map_layer_name); 
       holder.checkView = (ImageView) convertView.findViewById(R.id.map_layer_check); 

       convertView.setTag(holder); 
      } else 
       holder = (ViewHolder) convertView.getTag(); 

      MapLayer layer = getItem(position); 
      holder.iconView.setImageDrawable(getResources().getDrawable(layer.drawable)); 
      holder.nameView.setText(layer.name); 
      holder.checkView.setVisibility(layer.isActive ? View.VISIBLE : View.GONE); 

      return convertView; 
     } 

     public void updateItems(List<MapLayer> layers) { 
      mItems.clear(); 
      mItems.addAll(layers); 
      // notifyDataSetChanged(); 
     } 
    } 

    private static class ViewHolder { 
     ImageView iconView; 
     TextView nameView; 
     ImageView checkView; 
    } 

    interface MapLayerSelectedListener { 
     void OnMapLayerSelected(int index, String name); 
    } 
} 

발신자 (다른 활동에서) :

mapLayerSourceChooseDialog.updateData(layers); 
mapLayerSourceChooseDialog.show(getSupportFragmentManager(), null); 

그러나 나는 항상 NPE를 얻습니다. 대화 상자를 잘못 사용하면 어떻게됩니까?

누구든지 나를 확인할 수 있습니까?

+0

귀하의 logcat을 게시하십시오! –

답변

1

mapLayerSourceChooseDialog.updateData(layers)에 전화 할 때 mLayerAdapter이 초기화되었다고 가정하는 것이 문제입니다. 그건 맞지 않아. MapLayerSourceChooseDialog을 인스턴스화하면 onCreate()이 즉시 호출되지 않습니다.

두 가지 명백한 옵션 :

  1. 공급 조각에 인수로 List<MapLayer>. MapLayerSourceChooseDialogsetArguments() 및 방법을 사용하십시오. MapLayar 개체는 적어도 Serializable이어야하지만 바람직하게는 Parcelable을 구현해야합니다. 객체가 상당히 복잡하거나 목록의 크기가 상당히 크다면이 경로를 사용하지 않는 것이 좋습니다.
  2. List<MapLayer>을 리턴하는 getter로 수신기 인터페이스를 정의하십시오. 은 조각을 호스팅해야합니다. 그런 다음 MapLayerSourceChooseDialog에서 활동을 캐스팅하고 getter를 호출하여 데이터를 검색 할 수 있습니다. 이 접근법은 구현이 더 빠를 수 있지만 구성 변경시에 활동에 List<MapLayer>이 올바르게 유지되지 않으면 중단 될 수 있습니다.

두 접근법의 예는 documentation for DialogFragment에서 찾을 수 있습니다.

관련 문제