2013-12-11 2 views
2

Редактировать: проблема в том, что фрагмент отделяется от Activity. Однако я не знаю, как это предотвратить.android: getFragmentManager() возвращает null

У меня есть приложение, которое использует панель вкладок. Когда одна из вкладок нажата, она загружает список тем в пространстве под панелью вкладок. Одна из тем - «Направления». После нажатия на это пространство теперь заменяется макетом, который имеет верхнюю панель (под панелью вкладок), которая включает в себя кнопку «Назад» и кнопку «Получить маршруты». Ниже этого бара отображается карта Google. Если я нажму «Назад», я вернусь в список, как и ожидалось. Затем, если я нажму «Направления» в списке, я вернусь к карте, как ожидалось. Затем, если я снова нажму «Назад», вместо того, чтобы возвращать меня в список, это приведет к сбою приложения. Он показывает исключение NullPointerException, которое указывает на строку FragmentTransaction ft = getFragmentManager().beginTransaction(); внутри кнопки setOnClickListener на кнопке Back Button. Не уверен, почему он проигрывает фрагментатор.

Вот файл на вкладку, которая первоначально загружает список:

package org.childrensmuseum.visittcmindy; 

import java.util.ArrayList; 

import android.content.Context; 
import android.graphics.drawable.GradientDrawable; 
import android.graphics.drawable.GradientDrawable.Orientation; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentTransaction; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.TextView; 

public class InfoTab extends Fragment { 
    private ArrayList<InfoPage> pages; 
    private TCMSQLiteHelper sqliteHelper; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     sqliteHelper = new TCMSQLiteHelper(this.getActivity()); 
     pages = sqliteHelper.getAllPages(); 
     InfoPage directions = new InfoPage(); 
     directions.setPage_id(101); 
     directions.setTitle("Directions"); 
     InfoPage calendar = new InfoPage(); 
     calendar.setPage_id(102); 
     calendar.setTitle("Calendar"); 
     pages.add(1, directions); 
     pages.add(2, calendar); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.infolist, container, false); 
     ListView infoList = (ListView)v.findViewById(R.id.infolistview); 
     int[] colors = {0xFFCFE8FF,0xFFCFE8FF}; 
     infoList.setDivider(new GradientDrawable(Orientation.RIGHT_LEFT, colors)); 
     infoList.setDividerHeight(2); 

     ArrayList<String> valueList = new ArrayList<String>(); 
     for(InfoPage page : pages){ 
      valueList.add(page.getTitle()); 
     } 
     String[] values = new String[valueList.size()]; 
     values = valueList.toArray(values); 

     infoList.setAdapter(new InfoAdapter(getActivity(), values)); 

     infoList.setOnItemClickListener(new OnItemClickListener(){ 

      @Override 
      public void onItemClick(AdapterView<?> parent, View v, int p, 
        long id) { 
       long page_id = pages.get(p).getPage_id(); 
       // If Directions 
       if(page_id==101){ 
        DirectionsView directions = new DirectionsView(); 
        FragmentTransaction ft = getFragmentManager().beginTransaction(); 
        ft.replace(R.id.realtabcontent, directions); 
        ft.commit(); 
       } else { 
        PageDetails details = PageDetails.newInstance(pages.get(p).getPage_id()); 
        FragmentTransaction ft = getFragmentManager().beginTransaction(); 
        ft.replace(R.id.realtabcontent, details); 
        ft.commit(); 
       } 

      } 

     }); 
     return v; 
    } 

    private class InfoAdapter extends ArrayAdapter<String> { 

     public InfoAdapter(Context context, String[] values) { 
      super(context, R.layout.explorecell, values); 
      // TODO Auto-generated constructor stub 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 

      LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View row = inflater.inflate(R.layout.infocell,parent,false); 

      InfoPage page = pages.get(position); 

      if(position % 2 != 0){ 
       row.setBackgroundColor(getResources().getColor(R.color.listblue)); 
      } else { 
       row.setBackgroundColor(getResources().getColor(R.color.white)); 
      } 

      String page_icon = "page_" + page.getPage_id(); 
      ImageView iv = (ImageView)row.findViewById(R.id.infoImage); 
      TextView tv = (TextView)row.findViewById(R.id.infoText); 

      String title = page.getTitle(); 

      String[] titleParts = title.split("[ ]"); 
      String newTitle = ""; 
      for(int i=0;i<titleParts.length;i++){ 
       titleParts[i] = titleParts[i].substring(0,1).toUpperCase() + titleParts[i].substring(1); 
       newTitle += titleParts[i]; 
       if(i<titleParts.length-1){ 
        newTitle += " "; 
       } 
      } 

      iv.setImageResource(getActivity().getResources().getIdentifier(page_icon, "drawable","org.childrensmuseum.visittcmindy")); 
      tv.setText(newTitle); 
      return row; 
     } 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if(sqliteHelper != null) { 
      sqliteHelper.close(); 
     } 
    } 

} 

Вот файл для DirectionsView, который вызывается при нажатии кнопки этого пункта в списке:

package org.childrensmuseum.visittcmindy; 

import java.io.UnsupportedEncodingException; 
import java.net.URLEncoder; 
import java.util.List; 

import android.app.Dialog; 
import android.content.Intent; 
import android.location.Address; 
import android.location.Geocoder; 
import android.location.Location; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentTransaction; 
import android.util.Log; 
import android.view.InflateException; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesClient; 
import com.google.android.gms.location.LocationClient; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 

public class DirectionsView extends Fragment implements 
GooglePlayServicesClient.ConnectionCallbacks, 
GooglePlayServicesClient.OnConnectionFailedListener { 
    private static View v; 
    private MainApplication main; 
    private LocationClient mLocationClient; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     main = MainApplication.getInstance(); 
     mLocationClient = new LocationClient(getActivity(), this, this); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if(v != null){ 
      ViewGroup parent = (ViewGroup) v.getParent(); 
      if(parent != null){ 
       parent.removeView(v); 
      } 
     } 
     try { 
      mLocationClient.connect(); 
      v = inflater.inflate(R.layout.directions, container, false); 
      GoogleMap mMap; 
      mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.directionsmap)).getMap(); 
      Geocoder coder = new Geocoder(getActivity()); 
      List<Address> address; 

      try { 
       Log.d("DEBUG","2"); 
       String museumAddress = "The Children's Museum of Indianapolis, 3000 North Meridian St, Indianapolis, IN 46208"; 
       address = coder.getFromLocationName(museumAddress, 1); 
       Address museumLocation = address.get(0); 
       mMap.addMarker(new MarkerOptions() 
         .position(new LatLng(museumLocation.getLatitude(), museumLocation.getLongitude())) 
         .title(getResources().getString(R.string.museumTitle))); 
      } catch(Exception e) { 
       Log.d("DEBUG","Error Adding Marker: "+e.getLocalizedMessage()); 
      } 
      Button backButton = (Button)v.findViewById(R.id.backtoexhibits); 
      backButton.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        FragmentTransaction ft = getFragmentManager().beginTransaction(); 
        InfoTab infoTab = new InfoTab(); 
        ft.replace(R.id.realtabcontent, infoTab); 
        ft.commit(); 
       } 
      }); 

      Button directionsButton = (Button)v.findViewById(R.id.getdirections); 
      directionsButton.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        try { 
         openDirectionsDialog(); 
        } catch (UnsupportedEncodingException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      }); 
     } catch (InflateException e){ 
      /* map is already there, just return view as it is */ 
      e.printStackTrace(); 
     } 

     return v; 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult result) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onConnected(Bundle connectionHint) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onDisconnected() { 
     // TODO Auto-generated method stub 

    } 

    private void openDirectionsDialog() throws UnsupportedEncodingException{ 
     final Dialog dialog = new Dialog(getActivity()); 
     dialog.setContentView(R.layout.getdirections); 
     dialog.setTitle("Get Directions"); 
     Button useAddressBtn = (Button)dialog.findViewById(R.id.useAddress); 
     Button useLocationBtn = (Button)dialog.findViewById(R.id.useLocationBtn); 
     final EditText addressText = (EditText)dialog.findViewById(R.id.addressText); 
     final String museumAddress = URLEncoder.encode("The Children's Museum of Indianapolis, 3000 North Meridian St, Indianapolis, IN 46208","UTF-8"); 

     useAddressBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       String address; 
       try { 
        address = URLEncoder.encode(addressText.getText().toString(),"UTF-8"); 
        String url = "http://maps.google.com/maps?saddr="+address+"&daddr="+museumAddress; 
        Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url)); 
        intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"); 
        startActivity(intent); 
       } catch (UnsupportedEncodingException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 
     }); 

     useLocationBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Location mCurrentLocation = mLocationClient.getLastLocation(); 
       double lat = mCurrentLocation.getLatitude(); 
       double lng = mCurrentLocation.getLongitude(); 

       String url = "http://maps.google.com/maps?saddr="+lat+","+lng+"&daddr="+museumAddress; 
       Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url)); 
       intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"); 
       startActivity(intent); 

      } 
     }); 
     dialog.show(); 
    } 

} 

Редактировать :

Вот трассировки стека

12-11 14:07:03.547: E/AndroidRuntime(1846): FATAL EXCEPTION: main 
12-11 14:07:03.547: E/AndroidRuntime(1846): Process: org.childrensmuseum.visittcmindy, PID: 1846 
12-11 14:07:03.547: E/AndroidRuntime(1846): java.lang.NullPointerException 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at org.childrensmuseum.visittcmindy.DirectionsView$1.onClick(DirectionsView.java:80) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at android.view.View.performClick(View.java:4424) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at android.view.View$PerformClick.run(View.java:18383) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at android.os.Handler.handleCallback(Handler.java:733) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at android.os.Handler.dispatchMessage(Handler.java:95) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at android.os.Looper.loop(Looper.java:137) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at android.app.ActivityThread.main(ActivityThread.java:4998) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at java.lang.reflect.Method.invoke(Method.java:515) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) 
12-11 14:07:03.547: E/AndroidRuntime(1846):  at dalvik.system.NativeStart.main(Native Method) 

Edit 2:

Per предложения, я попытался заменить

FragmentTransaction ft = getFragmentManager().beginTransaction(); 

с

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); 

Там не было никаких изменений в ошибке.

+2

Опубликовать трассировку стека. так как вы используете фрагмент из библиотеки поддержки. и используйте 'getSupportFragmentManager()', так как у вас есть 'import android.support.v4.app.Fragment;' – Raghunandan

+0

@ Raghunandan yer fast! но, возможно, вы должны опубликовать это в качестве ответа – petey

+1

@petey i когда-нибудь будет отслеживать трассировку столбцов, и причина подтверждена. – Raghunandan

ответ

0

Вы смешали фрагмент и фрагмент поддержки. Для этого вы должны использовать библиотеку ActionBarSherlock. Итак, вам нужно расширить SherlockFragment, а не Fragment.

После этого, вам нужно использовать правку, что вы дали:

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); 

Это должно заставить его работать.

1

Я рекомендую это: http://developer.android.com/training/implementing-navigation/lateral.html

Это руководство по использованию в ViewPager и fragmentPagerAdapter с вкладок навигации, так что вам не придется вручную настроить onClickListener для изменения фрагментов. Это должно предотвратить отделение фрагментов.

Смежные вопросы