Я пытаюсь реализовать фрагменты проекта в Android Studio. Суть проекта состоит в том, чтобы выбрать цвет из счетчика в одном фрагменте, затем передать его родительскому действию и затем передать его из родительского действия во второй фрагмент, чтобы изменить цвет фона второго фрагмента. Проблема, с которой я сталкиваюсь, заключается в том, что мой слушатель в палитре активности имеет значение NULL, несмотря на то, что я вызываю его в функции onAttach
.
Это мой код фрагмента, который приводит к сбою приложения
package edu.temple.palettecolorapp;
import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Spinner;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link PaletteFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link PaletteFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class PaletteFragment extends Fragment {
private String colorArr[];
private String translationArr[];
Context parent;
private final String mParam1 = "colors";
private final String mParam2 = "translation";
public OnFragmentInteractionListener mListener;
public PaletteFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
*
* @return A new instance of fragment PaletteFragment.
*/
// TODO: Rename and change types and number of parameters
public static PaletteFragment newInstance(String colors[], String translation[]) {
PaletteFragment fragment = new PaletteFragment();
Bundle args = new Bundle();
args.putStringArray("colors", colors);
args.putStringArray("translation", translation);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
this.colorArr = getArguments().getStringArray(mParam1);
this.translationArr = getArguments().getStringArray(mParam2);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.parent = context;
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) parent;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
// this.parent = context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_palette, container, false);
Spinner spinner = v.findViewById(R.id.spinner);
PaletteAdapter pa = new PaletteAdapter(parent,colorArr,translationArr);
spinner.setAdapter(pa);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String c = colorArr[position];
mListener.onColorSelection(c);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return v;
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onColorSelection(String color);
}
}
Это основное занятие
package edu.temple.palettecolorapp;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
public class PaletteActivity extends AppCompatActivity implements PaletteFragment.OnFragmentInteractionListener {
PaletteFragment master;
ColorFragment subject;
FragmentTransaction ft;
private final String colors[] = {"blue", "green", "purple", "red", "gray", "cyan", "magenta", "yellow", "lime"};
private boolean isSelected = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getApplicationContext();
Resources res = context.getResources();
String title = res.getString(R.string.palette_title);
setTitle(title);
setContentView(R.layout.activity_palette);
String translation[] = res.getStringArray(R.array.colors);
PaletteFragment master = PaletteFragment.newInstance(colors,translation);
ColorFragment subject = ColorFragment.newInstance("magenta");
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment1,master);
ft.replace(R.id.fragment2,subject);
ft.addToBackStack(null);
ft.commit();
}
@Override
public void onColorSelection(String color) {
subject.updateBackgroundColor(color);
}
}
У меня возникли проблемы с этой частью фрагмента в методе onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_palette, container, false);
Spinner spinner = v.findViewById(R.id.spinner);
PaletteAdapter pa = new PaletteAdapter(parent,colorArr,translationArr);
spinner.setAdapter(pa);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String c = colorArr[position];
mListener.onColorSelection(c);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return v;
}
mListenerВызов .onColorSelection 'вызывает ошибку, и это то, что вывод
E/AndroidRuntime: FATAL EXCEPTION: main
Process: edu.temple.palettecolorapp, PID: 14867
java.lang.NullPointerException: Attempt to invoke virtual method 'void edu.temple.palettecolorapp.ColorFragment.updateBackgroundColor(java.lang.String)' on a null object reference
at edu.temple.palettecolorapp.PaletteActivity.onColorSelection(PaletteActivity.java:45)
at edu.temple.palettecolorapp.PaletteFragment$1.onItemSelected(PaletteFragment.java:87)
at android.widget.AdapterView.fireOnSelected(AdapterView.java:944)
at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:933)
at android.widget.AdapterView.access$300(AdapterView.java:53)
at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:898)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Edit2: добавлен ColorFragment метод updateBackgroundColor
import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* to handle interaction events.
* Use the {@link ColorFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ColorFragment extends Fragment {
private View v;
TextView t;
String color;
private final String KEY = "color";
public ColorFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters
* @return A new instance of fragment ColorFragment.
*/
// TODO: Rename and change types and number of parameters
public static ColorFragment newInstance() {
ColorFragment fragment = new ColorFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
this.color = getArguments().getString(KEY);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_color, container, false);
t = v.findViewById(R.id.textView);
t.setBackgroundColor(Color.BLACK);
return v;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
public void updateBackgroundColor(String c){ // causing problems
t.setBackgroundColor(Color.parseColor(c));
}
}