我目前正在尝试在片段上创建自定义对话框,以将文本带回片段。我有对话框设置,但是当我单击按钮以弹出对话框时,出现此错误。
java.lang.ClassCastException: com.example.android.app.MainActivity@4c01a76must implement StatusDialogListener
然后我发现this stack post在谈论这个问题
从阅读错误和堆栈后看来,问题似乎是我必须在连接到片段的活动上实现对话框类。
所以我将监听器实现了我的主要活动
public class MainActivity extends AppCompatActivity implements ... Status_Dialog.StatusDialogListner
实施后,出现以下错误:
Class 'MainActivity' must either be declared abstract or implement abstract method 'applyText(String)' in 'StatusDialogListner
我通过将以下代码添加到“活动”中来解决此问题:
@Override
public void applyText(String status) {
}
这允许该应用程序运行并显示对话框而没有错误。
现在的问题是我的适配器无法从对话框中获取文本,因此我认为这与以下事实有关:我在运行调试器applyText
时在片段和主要活动中也有一个applytext
片段中从未调用过。此时我迷路了
代码
对话框
public class Status_Dialog extends AppCompatDialogFragment {
private EditText editTextStatus;
private StatusDialogListner listner;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.layout_status_dialog, null);
editTextStatus = view.findViewById(R.id.new_status);
builder.setView(view)
.setTitle("Change Status")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String status = editTextStatus.getText().toString();
listner.applyText(status);
}
});
return builder.create();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listner = (StatusDialogListner) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement StatusDialogListener");
}
}
public interface StatusDialogListner {
void applyText(String status);
}
}
片段
public class profile_fragment extends Fragment implements Status_Dialog.StatusDialogListner {
private static final int GALLERY_PICK = 1;
private DatabaseReference mUserDatabase;
//Android Layout
private FirebaseUser mCurrentUser;
private CircleImageView mDisplayImage;
private TextView mName;
private TextView mStatus;
private Button mStatusBtn;
private Button mImageBtn;
private ProgressDialog mProgressDialog;
private StorageReference mImageStorage;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListner;
private static final String KEY_NAME = "name";
private static final String KEY_STATUS = "status";
private static final String KEY_IMAGE = "image";
private static final String TAG = "user_profile";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile_fragment, container, false);
mDisplayImage = view.findViewById(R.id.profile_picture);
mName = view.findViewById(R.id.profile_user_name);
mStatus = view.findViewById(R.id.profile_user_status);
mStatusBtn = view.findViewById(R.id.profile_change_status_btn);
mImageBtn = view.findViewById(R.id.profile_change_image_btn);
mImageStorage = FirebaseStorage.getInstance().getReference();
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
final String current_uid = mCurrentUser.getUid();
DocumentReference mUsersDB = db.collection("Users").document(current_uid);
// FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser() ;
// Toast.makeText(this, "ttt" + currentFirebaseUser.getUid(), Toast.LENGTH_SHORT).show();
mStatusBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openDialog();
/*
String status_value = mStatus.getText().toString();
Intent status_intent = new Intent(getActivity(), change_status.class);
status_intent.putExtra("status_value", status_value);
startActivity(status_intent);
*/
}
});
mImageBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent, "Select Image"), GALLERY_PICK);
/*
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.start(SettingsActivity.this);
*/
}
});
mUsersDB.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists()) {
String name = documentSnapshot.getString(KEY_NAME);
mName.setText(name);
String status = documentSnapshot.getString(KEY_STATUS);
mStatus.setText(status);
FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
} else {
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
});
return view;
}
public void openDialog(){
Status_Dialog status_dialog = new Status_Dialog();
status_dialog.show(getActivity().getSupportFragmentManager(), "TEST?");
}
@Override
public void applyText(String status) {
mStatus.setText(status);
}
...
答案 0 :(得分:0)
问题在这里:
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listner = (StatusDialogListner) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement StatusDialogListener");
}
}
请注意,列表器是在onAttach
期间设置的,它正在接收Context
的实例。换句话说,它正在接收主机活动的实例(这就是为什么您必须在MainActivity
中实现接口的原因)
我认为您可以按以下方式更新代码:
1)从对话框中删除它。这样,您的活动就不再必须实现StatusDialogListener
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listner = (StatusDialogListner) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + "must implement StatusDialogListener");
}
}
2)在对话框上更新它:
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if(listner != null) { // ADD THIS NULL CHECK SINCE LISTNER MAY BE NULL
String status = editTextStatus.getText().toString();
listner.applyText(status);
}
}
});
3)将此添加到对话框:
public void setListener(StatusDialogListner newListener) {
this.listner = newListener;
}
4)在片段上对其进行更新:
public void openDialog(){
Status_Dialog status_dialog = new Status_Dialog();
status_dialog.setListener(this); // ADD THIS NEW LINE
status_dialog.show(getActivity().getSupportFragmentManager(), "TEST?");
}
5)从MainActivity
// Remove the implementation of Status_Dialog.StatusDialogListner from MainActivity
// And remove the method below:
@Override
public void applyText(String status) {
}