У меня есть эта проблема, когда я хочу передать данные из списка в любое текстовое представление или отредактировать представление для фрагмента: попытка вызвать виртуальный метод void android.widget.EditText.setText (java.lang.CharSequence) для ссылки на нулевой объект Я использую Butterknife, и это инициируется в onCreateView. Что случилось?
Метод во фрагменте:
@Override
public void itemData(int position, List<Task> tasks) {
Task task = tasks.get(position);
taskID = task.getId();
String taskTexT = task.getDate();
titleEdit.setText(task.getText());
Log.d(TAG, "EDIT FRAGMENT " + position + task + taskTexT);
}
Масляный нож во фрагменте:
@BindView(R.id.time_edit) TextView timeEdit;
@BindView(R.id.date_edit) TextView dateEdit;
@BindView(R.id.title_edit) EditText titleEdit;
@BindView(R.id.save_edit_button) Button saveEditButton;
И файл XML:
<?xml version = "1.0" encoding = "utf-8"?>
<FrameLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:id = "@+id/edit_fragment">
<RelativeLayout
android:layout_width = "match_parent"
android:layout_height = "300dp"
android:background = "@color/colorPrimaryDark">
<EditText
android:id = "@+id/title_edit"
android:layout_width = "330dp"
android:layout_height = "60dp"
android:layout_alignParentTop = "true"
android:layout_centerHorizontal = "true"
android:layout_marginTop = "35dp"
android:backgroundTint = "#FFF"
android:textColor = "#FFF" />
<TextView
android:id = "@+id/date_edit"
android:layout_width = "130dp"
android:layout_height = "40dp"
android:layout_alignTop = "@+id/and"
android:layout_toStartOf = "@+id/and"
android:clickable = "true"
android:focusable = "true"
android:gravity = "center"
android:hint = "Select date"
android:textColor = "#FFF"
android:textColorHint = "#FFF"
android:textSize = "18sp" />
<View
android:id = "@+id/line"
android:layout_width = "320dp"
android:layout_height = "1dp"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:layout_marginBottom = "119dp"
android:background = "#FFF" />
<TextView
android:id = "@+id/time_edit"
android:layout_width = "132dp"
android:layout_height = "40dp"
android:layout_above = "@+id/line"
android:layout_toEndOf = "@+id/and"
android:clickable = "true"
android:focusable = "true"
android:gravity = "center"
android:hint = "Select time"
android:textAlignment = "center"
android:textColor = "#FFF"
android:textColorHint = "#FFF"
android:textSize = "18sp" />
<TextView
android:id = "@+id/and"
android:layout_width = "40dp"
android:layout_height = "40dp"
android:layout_above = "@+id/line"
android:layout_centerHorizontal = "true"
android:gravity = "center"
android:text = "and"
android:textColor = "#FFF"
android:textSize = "18sp" />
<Button
android:id = "@+id/save_edit_button"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:layout_marginBottom = "36dp"
android:text = "EDIT"/>
</RelativeLayout>
EditFragment:
public class EditFragment extends Fragment implements IRecyclerItemData {
private static final String TAG = "EditFragment";
@BindView(R.id.time_edit) TextView timeEdit;
@BindView(R.id.date_edit) TextView dateEdit;
@BindView(R.id.title_edit) EditText titleEdit;
@BindView(R.id.save_edit_button) Button saveEditButton;
private DatePickerDialog.OnDateSetListener mDateEditListener;
private TimePickerDialog.OnTimeSetListener mTimeEditListener;
List<Task> tasks;
String taskID;
RealmHelper realmHelper;
Realm realm;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_fragment, container, false);
ButterKnife.bind(this, view);
((MainActivity) getActivity()).hideFloatingActionButton();
Realm.init(getActivity());
RealmConfiguration configuration = new RealmConfiguration
.Builder()
.deleteRealmIfMigrationNeeded()
.build();
realm = Realm.getInstance(configuration);
realmHelper = new RealmHelper(realm);
tasks = new ArrayList<>();
tasks = realmHelper.getAllTasks();
mDateEditListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
month = month + 1;
Log.d(TAG, "onDataEditSet: dd/mm/yyyy: " + year + "/" + month + "/" + dayOfMonth);
String date = dayOfMonth + "/" + month + "/" + year;
dateEdit.setText(date);
}
};
mTimeEditListener = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Log.d(TAG, "onTimeEditSet: hh/mm: " + hourOfDay + "/" + minute);
String time = hourOfDay + ":" + minute;
timeEdit.setText(time);
}
};
return view;
}
@OnClick(R.id.date_edit)
public void onEditDateClick() {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(getActivity(), android.R.style.Theme_Holo_Light_Dialog_MinWidth, mDateEditListener,
year, month, day);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
}
@SuppressLint("ResourceType")
@OnClick(R.id.time_edit)
public void onEditTimeClick() {
Calendar calendar = Calendar.getInstance();
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
TimePickerDialog dialog = new TimePickerDialog(getActivity(), android.R.style.Theme_Holo_Light_Dialog_MinWidth, mTimeEditListener,
hourOfDay, minute, DateFormat.is24HourFormat(getActivity()));
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
}
@OnClick(R.id.save_edit_button)
public void onEditSaveClick() {
}
@Override
public void itemData(int position, List<Task> tasks) {
Task task = tasks.get(position);
taskID = task.getId();
String taskTexT = task.getDate();
titleEdit.setText(task.getText());
Log.d(TAG, "EDIT FRAGMENT " + position + task + taskTexT);
}
}
Это часть адаптера RV, где я вызываю itemData:
@Override
public void onBindViewHolder(@NonNull final TaskViewHolder holder, @SuppressLint("RecyclerView") final int position) {
final Task task = tasks.get(position);
holder.textItem.setText(task.getText());
holder.dateItem.setText(task.getDate());
holder.timeItem.setText(task.getTime());
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
callback.onDeleteClick(position);
notifyItemRemoved(holder.getAdapterPosition());
Log.d(TAG, "DELETE_CLICK " + holder.getAdapterPosition());
}
});
holder.editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
callback.onEditClick(position);
callback2.itemData(position, tasks);
}
});
}
Основная деятельность:
public class MainActivity extends AppCompatActivity implements IRecyclerItemClickListener {
@Nullable
@BindView(R.id.floating_button) FloatingActionButton floatingButton;
RecyclerView recyclerView;
MainAdapter mainAdapter;
EditFragment editFragment = new EditFragment();
Realm realm;
RealmHelper realmHelper;
List<Task> tasks;
String taskID;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
recyclerView = findViewById(R.id.recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
Realm.init(this);
RealmConfiguration configuration = new RealmConfiguration
.Builder()
.deleteRealmIfMigrationNeeded()
.build();
realm = Realm.getInstance(configuration);
realmHelper = new RealmHelper(realm);
tasks = new ArrayList<>();
tasks = realmHelper.getAllTasks();
mainAdapter = new MainAdapter(tasks, this, new IRecyclerItemData() {
@Override
public void itemData(int position, List<Task> tasks) {
editFragment.itemData(position, tasks);
}
});
recyclerView.setAdapter(mainAdapter);
recyclerView.setHasFixedSize(true);
}
@Optional
@OnClick(R.id.floating_button)
public void onClick() {
android.app.Fragment fragment = new TaskFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_activity, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
public void showFloatingActionButton() {
floatingButton.show();
}
public void hideFloatingActionButton() {
floatingButton.hide();
}
@Override
public void onBackPressed() {
super.onBackPressed();
showFloatingActionButton();
recyclerView.removeAllViews();
}
@Override
protected void onDestroy() {
realm.close();
super.onDestroy();
}
@Override
public void onDeleteClick(int position) {
Task task = tasks.get(position);
taskID = task.getId();
if (taskID != null) {
realmHelper.deleteTask(taskID);
Log.d(TAG, "ON DELETE CLICK " + taskID);
Toast.makeText(getApplicationContext(), "Task removed", Toast.LENGTH_LONG).show();
}
}
@Override
public void onEditClick(int position) {
Fragment fragment = new EditFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_activity, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
У меня есть это в onCreateView
вы всегда получаете этот сбой?
@ user9897182 поделитесь своим классом фрагмента.
@RishabhSaxena Да, он все еще там.
@KrishnaSharma Я только что вставил фрагмент
Также поделитесь фрагментом кода, из которого вы вызываете метод itemData
Ok. Я вставил код. Это часть адаптера RV.
Из фрагмента EditFragment, где вы вызываете этот адаптер? Не нашел ни одной инициализации адаптера.
Из MainActivity. Вы хотите код этого действия?
да, пожалуйста, если вы инициализируете адаптер из активности, то определенно проблема существует.
Хорошо, я только что это сделал. Надеюсь, ты что-нибудь найдешь.
Итак, вот в чем проблема: вы не добавили EditFragment в свой класс активности, но пытаетесь получить доступ к методу editFragment.itemData. выполнив EditFragment editFragment = new EditFragment (); не означает, что ваш фрагмент добавляется к действию и вызывается весь метод жизненного цикла фрагмента. Фактически ни один из методов жизненного цикла фрагмента не вызывается, а представления не инициализируются. поэтому очевидно, что вы получите NPE.We could have simple fix for this but I don't understand your requirement.I would suggest you to call fragment methods only if your fragment is attached to the activity
Простое исправление - просто закомментировать эту строку из действия editFragment.itemData (должность, задачи);.
Хорошо, но как добавить фрагмент в Activity? Я добавил фрагмент и все то же самое. Как ваше предложение?
Убедитесь, что вы вызываете ButterKnife.bind (это, просмотр) для инициализации.
@BindView(R.id.time_edit)
TextView timeEdit;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_layout, container, false);
ButterKnife.bind(this, view);
return view;
}
У меня это есть в onCreateView.
В своем фрагменте вызовите ButterKnife.bind(this, view); в onCreateView(); непосредственно перед возвратом view.
Я использую это.
@ user9897182
Иногда мы получаем результат, когда наш фрагмент уже уничтожен.
Я рекомендую вам обернуть ваш код в:
if (isAdded()&&!getActivity().isFinishing()){
//Todo add your code here
}
Я добавил этот код в itemData, и приложение не вылетает, но я ничего не вижу в edittext и textviews. Логи тоже пустые. Я использовал отладчик и такой же - ничего.
@ user9897182 Итак, очевидно, что ваш фрагмент уже уничтожен. Найдите причину этого. Вы больше ничего не можете сделать.
отладить оператор if ()
Я сделал это, и метод получил позицию и список данных, но taskID имеет значение null. А как насчет фрагмента диалога? Это может решить проблему?
Убедитесь, что вы звоните ButterKnife.bind (это, просмотр);