Поддержка Android v14 PreferenceFragment вылетает
Я пытаюсь отобразить настройки в приложении Android с помощью PreferenceFragment из android.support.v14.preference
библиотека. Однако, когда я пытаюсь открыть настройки, приложение вылетает со странным исключением NullPointerException. Этого не произойдет, если я пропущу звонок addPreferenceFromResource(R.xml.preferences)
в моем PreferenceFragment, но тогда, конечно, предпочтения никогда не будут показаны.
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)
Я читал, что support-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);
}
}
2 ответа
PreferenceFragment
уже раздувает соответствующий макет для использования - используя свой собственный R.layout.fragment_settings
, он не может найти соответствующие представления, которые ему требуются.
Если вы хотите изменить 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;
}
Закомментируй свой onCreateView()
метод.
Или цепочка к реализации суперкласса onCreateView()
и вставьте его ответ в свою собственную обертку, если по какой-то причине вы хотите дополнительные вещи вокруг запаса PreferenceFragment
UI.
PreferenceFragment
вероятно, ожидает его onCreateView()
создать RecyclerView
чего не хватает в вашей трассировке стека.