gpt4 book ai didi

java - 从适配器返回到 fragment 后获取上下文

转载 作者:行者123 更新时间:2023-11-29 22:37:30 25 4
gpt4 key购买 nike

我在我的 fragment (“UnitsFragment.java”)中使用上下文操作栏来删除和编辑 recyclerview 的项目。但是当我从 recyclerview 适配器类(“UnitsRv.java”)回来时。上下文似乎为空。我尝试从适配器返回上下文,它适用于函数“prepareSelection”。但是对于 ActionMode.callback 下的“onActionItemClicked”,我需要获取上下文以便我可以使用 alertdialog 来编辑项目。

The "requireContext()" throws this error: Fragment UnitsFragment{e3a36c8 (b4957397-055a-4b1c-8af2-fee89a3e9b35)} not attached to a context. Here are my codes. UnitsFragment.java

public class UnitsFragment extends Fragment {
private static final String TAG = "UnitsFragment";

private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
ArrayList<UnitsList> unitsLists = new ArrayList<>();
Activity mcontext = getActivity();
Context dcontext;

ActionMode actionMode;
public static ArrayList<UnitsList> selectionList = new ArrayList<>();
public static boolean isInActionMode = false;

List<String> list = DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao().findUnitNameList();

public UnitsFragment() {
}

private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_item_action, menu);
return true;
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_edit:
if (selectionList.size() == 1) {
final EditText editText = new EditText(requireContext());
new AlertDialog.Builder(requireContext())
.setTitle("Rename unit name").setView(editText)
.setPositiveButton("Rename", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
UnitsList unitsList = selectionList.get(0);
unitsList.setUnit_name(editText.getText().toString().trim());
isInActionMode = false;
((UnitsRv) mAdapter).changeDataItem(getCheckedLastPosition(), unitsList);
actionMode.finish();
selectionList.clear();
}
})
.create()
.show();
Toast.makeText(getContext(), "Edit", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
case R.id.menu_item_delete:
isInActionMode = false;
((UnitsRv) mAdapter).removeData(selectionList);
Toast.makeText(getContext(), "Delete", Toast.LENGTH_SHORT).show();
actionMode.finish();
selectionList.clear();
return true;
default:
return false;

}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};

private int getCheckedLastPosition() {
ArrayList<UnitsList> dataSet = UnitsRv.getDataSet();
for (int i = 0; i < dataSet.size(); i++) {
if (dataSet.get(i).equals(selectionList.get(0))) {
return i;
}
}
return 0;
}


@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}

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

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_units, container, false);
setHasOptionsMenu(true);

dcontext = rootView.getContext();
Log.d(TAG, "onCreateView1: " + dcontext);
recyclerView = rootView.findViewById(R.id.rv_units);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.HORIZONTAL));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL));
layoutManager = new GridLayoutManager(getContext(), 2);
recyclerView.setLayoutManager(layoutManager);


for (String string : list) {
unitsLists.add(new UnitsList(string));
}
Log.d(TAG, "onCreateView: " + getContext());
mAdapter = new UnitsRv(mcontext,unitsLists);
recyclerView.setAdapter(mAdapter);

return rootView;
}

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.add, menu);
super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new:
final View customLayout = getLayoutInflater().inflate(R.layout.add_unit_dialog, null);
final EditText edt_unit_name = customLayout.findViewById(R.id.edt_new_unit_name);
final AlertDialog dialog = new AlertDialog.Builder(getContext())
.setView(customLayout)
.setTitle("Unit name")
.setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
.setNegativeButton(android.R.string.cancel, null)
.create();

dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
Button ok_btn = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
Button cancel_btn = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);

ok_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String unit_name = edt_unit_name.getText().toString().trim();
if (!TextUtils.isEmpty(unit_name)) {
String old_unit_name = DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao()
.findByUnitName(unit_name);
if (old_unit_name == null) {
DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao()
.insertUnits(new UnitsList(unit_name));
unitsLists.add(new UnitsList(unit_name));
dialog.dismiss();
} else {
edt_unit_name.setError("Unit already exists");
}

} else {
edt_unit_name.setError("Can't be empty");
}
}
});

cancel_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
}
});
dialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}

public void prepareSelection(Context context,int position) {
if(actionMode == null) {
isInActionMode = true;

for (String string : list) {
unitsLists.add(new UnitsList(string));
}
mAdapter = new UnitsRv(context, unitsLists);
Log.d(TAG, "prepareSelection: " + mAdapter);
Log.d(TAG, "prepareSelection1: " + dcontext);
mcontext = (Activity)context;
actionMode = mcontext.startActionMode(actionModeCallback);

mAdapter.notifyDataSetChanged();

if (!selectionList.contains(unitsLists.get(position))) {
selectionList.add(unitsLists.get(position));
}
updateViewCounter();
}
}

private void updateViewCounter() {
int counter = selectionList.size();
if (counter == 1) {
actionMode.setTitle(counter + "item selected");
} else {
actionMode.setTitle(counter + "items selected");
}
}
}

这是我的适配器类。UnitsRv.java

public class UnitsRv extends RecyclerView.Adapter<UnitsRv.ViewHolder> {
private static final String TAG = "UnitsRv";

private static ArrayList<UnitsList> munitsLists = new ArrayList<>();
UnitsFragment unitsFragment = new UnitsFragment();
Context mcontext;

public UnitsRv(Context context,ArrayList<UnitsList> unitsLists) {
mcontext = context;
munitsLists = unitsLists;
}

class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView unit_name;

public ViewHolder(View v) {
super(v);
unit_name = v.findViewById(R.id.unit_name);

v.setOnLongClickListener(this);
}


@Override
public void onClick(View view) {
if (UnitsFragment.isInActionMode){
unitsFragment.prepareSelection(mcontext,getAdapterPosition());
notifyItemChanged(getAdapterPosition());
}
}

@Override
public boolean onLongClick(View view) {
Log.d(TAG, "onLongClick: " + getAdapterPosition());
unitsFragment.prepareSelection(view.getContext(),getAdapterPosition());
return true;
}
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.units_item, parent, false);
return new ViewHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
holder.unit_name.setText(munitsLists.get(position).getUnit_name());
if (UnitsFragment.isInActionMode){
if (UnitsFragment.selectionList.contains(munitsLists.get(position))){
holder.itemView.setBackgroundResource(R.color.colorSelected);
}
}

}

@Override
public int getItemCount() {
return munitsLists.size();
}

public static ArrayList<UnitsList> getDataSet() {
return munitsLists;
}

public void changeDataItem(int position, UnitsList unitsList) {
munitsLists.set(position, unitsList);
notifyDataSetChanged();
}

public void removeData(ArrayList<UnitsList> list) {
for (UnitsList unitsList : list) {
munitsLists.remove(unitsList);
}
notifyDataSetChanged();
}
}

最佳答案

首先,您不应在适配器内创建 UnitsFragment实例

您可以使用 EventBus在 Activity 、 fragment 、适配器等之间进行通信。

或者您可以使用接口(interface) 完成您的任务。如下所示。

像这样创建一个界面

public interface AdapterCallback {
void prepareSelection(Context context,int position);
}

在您的UnitsFragment 中实现上述接口(interface)。像下面这样

public class UnitsFragment extends Fragment implements AdapterCallback{ 

// your other codes

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_units, container, false);
setHasOptionsMenu(true);

// .... your other codes

Log.d(TAG, "onCreateView: " + getContext());

// modify below line like this
mAdapter = new UnitsRv(mcontext, unitsLists, this); // here you have to pass an extra parameter that will implement your callback method from adapter.

recyclerView.setAdapter(mAdapter);

return rootView;
}

// ... you other codes

@Override
public void prepareSelection(Context context,int position) {
if(actionMode == null) {
isInActionMode = true;

for (String string : list) {
unitsLists.add(new UnitsList(string));
}
mAdapter = new UnitsRv(context, unitsLists,this); // add this as parameter.
Log.d(TAG, "prepareSelection: " + mAdapter);
Log.d(TAG, "prepareSelection1: " + dcontext);
mcontext = (Activity)context;
actionMode = mcontext.startActionMode(actionModeCallback);

mAdapter.notifyDataSetChanged();

if (!selectionList.contains(unitsLists.get(position))) {
selectionList.add(unitsLists.get(position));
}
updateViewCounter();
}
}
// other codes
}

现在,在您的 Adapter 中,您需要在 UnitsRvconstructor 中添加一个额外的 argument 并调用您的interface 来自适配器的方法,使用 mAdapterCallback

public class UnitsRv extends RecyclerView.Adapter<UnitsRv.ViewHolder> {
private static final String TAG = "UnitsRv";

private static ArrayList<UnitsList> munitsLists = new ArrayList<>();
UnitsFragment unitsFragment = new UnitsFragment(); // remove this line
private AdapterCallback mAdapterCallback; // add this line
Context mcontext;

public UnitsRv(Context context,ArrayList<UnitsList> unitsLists, AdapterCallback callback) {
mcontext = context;
munitsLists = unitsLists;
this.mAdapterCallback = callback; // add this line
}

class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView unit_name;

public ViewHolder(View v) {
super(v);
unit_name = v.findViewById(R.id.unit_name);

v.setOnLongClickListener(this);
}


@Override
public void onClick(View view) {
if (UnitsFragment.isInActionMode){
mAdapterCallback.prepareSelection(mcontext,getAdapterPosition()); // modify this line
notifyItemChanged(getAdapterPosition());
}
}

@Override
public boolean onLongClick(View view) {
Log.d(TAG, "onLongClick: " + getAdapterPosition());
mAdapterCallback.prepareSelection(view.getContext(),getAdapterPosition()); // modify this line
return true;
}
}
// your other codes....

}

关于java - 从适配器返回到 fragment 后获取上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59367931/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com