2

Я пытаюсь отобразить настройки в Android-приложении, используя PreferenceFragment из библиотеки android.support.v14.preference. Однако, когда я пытаюсь открыть настройки, приложение вылетает со странным исключением NullPointerException. Этого не происходит, если я оставляю вызов addPreferenceFromResource(R.xml.preferences) в моем PreferenceFragment, но тогда, конечно, настройки никогда не отображаются.Поддержка android v14 PreferenceFragment crashes

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hardboard.preferencetest/com.hardboard.preferencetest.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
      at android.app.ActivityThread.access$800(ActivityThread.java:156) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:211) 
      at android.app.ActivityThread.main(ActivityThread.java:5373) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference 
      at android.support.v14.preference.PreferenceFragment.bindPreferences(PreferenceFragment.java:473) 
      at android.support.v14.preference.PreferenceFragment.onActivityCreated(PreferenceFragment.java:278) 
      at android.app.Fragment.performActivityCreated(Fragment.java:2061) 
      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:912) 
      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
      at android.app.BackStackRecord.run(BackStackRecord.java:834) 
      at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452) 
      at android.app.Activity.performStart(Activity.java:6005) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2342) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
            at android.app.ActivityThread.access$800(ActivityThread.java:156) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:211) 
            at android.app.ActivityThread.main(ActivityThread.java:5373) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:372) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 

Я прочитал, что поддержка-v14 PreferenceFragment использует RecyclerView внутренне для отображения списка предпочтений, но то, что я делаю неправильно, чтобы привести в RecyclerView быть null?

Моя основная активность:

public class MainActivity extends AppCompatActivity implements SettingsFragment.OnFragmentInteractionListener { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     getFragmentManager().beginTransaction() 
       .replace(android.R.id.content, new SettingsFragment()) 
       .addToBackStack(null) 
       .commit(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onFragmentInteraction(Uri uri) { 

    } 
} 

PreferenceFragment:

public class SettingsFragment extends android.support.v14.preference.PreferenceFragment { 

    private OnFragmentInteractionListener mListener; 

    public SettingsFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    } 

    @Override 
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 
     addPreferencesFromResource(R.xml.preferences); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     return inflater.inflate(R.layout.fragment_settings, container, false); 
    } 

    // TODO: Rename method, update argument and hook method into UI event 
    public void onButtonPressed(Uri uri) { 
     if (mListener != null) { 
      mListener.onFragmentInteraction(uri); 
     } 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     try { 
      mListener = (OnFragmentInteractionListener) context; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(context.toString() 
        + " must implement OnFragmentInteractionListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 

    public interface OnFragmentInteractionListener { 
     public void onFragmentInteraction(Uri uri); 
    } 

} 
+0

, пожалуйста, напишите 'xml' для' fragment_settings' – Tauqir

ответ

7

Если вы хотите изменить само устройство RecyclerView, рассмотрите возможность переустановки onCreateRecyclerView(). Если вместо этого вы хотите создать нестандартную структуру вокруг макета по умолчанию, вы можете использовать шаблон, такой как:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    final View view = inflater.inflate(R.layout.fragment_settings, container, false); 
    // The frame you want to embed the parent layout in. 
    final ViewGroup innerContainer = (ViewGroup) view.findViewById(R.id.main_frame); 
    final View innerView = super.onCreateView(inflater, innerContainer, savedInstanceState); 
    if (innerView != null) { 
     innerContainer.addView(innerView); 
    } 
    return view; 
} 
0

Закомментируйте ваш метод onCreateView().

Или, цепь для реализации суперкласса onCreateView() и встроить его ответ в свою собственную упаковку, если по какой-то причине вы хотите получить дополнительную информацию об акции PreferenceFragment UI.

PreferenceFragment, возможно, ожидает, что его onCreateView() создаст RecyclerView, отсутствующий на вашей трассе стека.