如何修复:“无法将 activity 转换为片段
How to fix :"Cannot cast activity to fragment
我想要设置片段但仍然在 mainactivity 中访问父级activity。
我有 3 个布局 mainActivity M、片段 A 和布局弹出窗口 B,它们在片段 A 上的按钮点击时显示。
我想将数据从布局 B(片段)发送到带有界面的片段 A。 onAttach 程序,设置片段时它不起作用。仍在访问父 activity。此零点的结果。
这里的错误代码位于:
interfaceOnInputListener = (OnInputListener) context;
我尝试用 getActivity().getApplicationContext()
替换上下文。但是还是不行。
这里是 myPopUpWindow 中的完整代码
public class myPopUpWindow extends DialogFragment {
private static final String TAG = "myPopUpWindow";
public interface OnInputListener{
void sendOutput(String output);
}
public OnInputListener interfaceOnInputListener;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.popup_wind,container,false);
final TextView tbxEdT = (TextView) view.findViewById(R.id.editText);
Button btnOK = (Button) view.findViewById(R.id.btnOk);
btnOK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String strInput = tbxEdT.getText().toString();
interfaceOnInputListener.sendOutput(strInput);
getDialog().dismiss();
}
});
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
interfaceOnInputListener = (OnInputListener) context;
} catch (ClassCastException e) {
Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
}
}
}
这是主要activity代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadFragment();
}
private boolean loadFragment(){
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_container,new AFragment())
.addToBackStack(null)
.commit();
return true;
}
}
此处 xml 包含片段
的框架
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="395dp"
android:layout_height="715dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
我想将数据从 myPopUpWindow 发送到片段 A。但是将 activity 转换为片段时出错。有什么建议吗?
我不确定你是如何管理它的,因为你没有分享 activity 代码。您不应该直接将 context
转换为您的界面。这可能会导致潜在的崩溃以及创建错误的代码,因为您的对话片段依赖于其调用者来实现。尝试使用以下方法。
在您的对话片段中:
public class YourDialogFragment : DialogFragment {
@Nullable private OnInputListener onInputListener;
public setInputListener(onInputListener : OnInputListener) {
this.onInputListener = onInputListener
}
//Other codes here
//Make sure to null check with this code before sending
// if (this.onInputListener != null) { onInputListener.doSth() }
@Override
public void onDestroy {
this.interfaceOnInputListener = null
super. onDestroy()
}
}
然后你可以在创建dialog fragment的时候通过暴露的方法来设置监听器,比如说你的activty中有这个功能
class YourActivity : AppCompatActivity {
public void showDialog() {
public final dialogFragment = YourDialogFragment()
dialogFragment.setInputListener(this) //this can be whatever interface implmenetation you want
dialogFragment.show(getSupportFragmentManager(), "TAG_HERE")
}
}
这样即使后面重构逻辑,也不用担心类型转换失败或者context为null。这种方法的另一个好处是片段不再依赖于它的调用者来实现接口,所以它也有利于以后的测试。
经过各种变通,问题终于解决了。但我有意更改它并在 Fragment A 上,在 ActivityResult 上得到它。
弹出对话框中的代码
Intent intent = new Intent();
intent.putExtra("class",spnSubClass.getSelectedItem().toString());
intent.putExtra("month",strSelectedMonth);
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
dismiss();
并在片段 A 中得到它:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case POPUPDIALOG:
if (resultCode == Activity.RESULT_OK) {
//--- get value from dialog
Bundle bundle = data.getExtras();
strClass = bundle.getString("class");
strMonth = bundle.getString("month");
} else if (resultCode == Activity.RESULT_CANCELED) {
//
}
break;
}
}
interfaceOnInputListener = (OnInputListener) getTargetFragment();
这是一个类似的程序。请参阅此以获得更多理解。
我想要设置片段但仍然在 mainactivity 中访问父级activity。
我有 3 个布局 mainActivity M、片段 A 和布局弹出窗口 B,它们在片段 A 上的按钮点击时显示。 我想将数据从布局 B(片段)发送到带有界面的片段 A。 onAttach 程序,设置片段时它不起作用。仍在访问父 activity。此零点的结果。 这里的错误代码位于:
interfaceOnInputListener = (OnInputListener) context;
我尝试用 getActivity().getApplicationContext()
替换上下文。但是还是不行。
这里是 myPopUpWindow 中的完整代码
public class myPopUpWindow extends DialogFragment {
private static final String TAG = "myPopUpWindow";
public interface OnInputListener{
void sendOutput(String output);
}
public OnInputListener interfaceOnInputListener;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.popup_wind,container,false);
final TextView tbxEdT = (TextView) view.findViewById(R.id.editText);
Button btnOK = (Button) view.findViewById(R.id.btnOk);
btnOK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String strInput = tbxEdT.getText().toString();
interfaceOnInputListener.sendOutput(strInput);
getDialog().dismiss();
}
});
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
interfaceOnInputListener = (OnInputListener) context;
} catch (ClassCastException e) {
Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
}
}
}
这是主要activity代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadFragment();
}
private boolean loadFragment(){
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_container,new AFragment())
.addToBackStack(null)
.commit();
return true;
}
}
此处 xml 包含片段
的框架<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="395dp"
android:layout_height="715dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
我想将数据从 myPopUpWindow 发送到片段 A。但是将 activity 转换为片段时出错。有什么建议吗?
我不确定你是如何管理它的,因为你没有分享 activity 代码。您不应该直接将 context
转换为您的界面。这可能会导致潜在的崩溃以及创建错误的代码,因为您的对话片段依赖于其调用者来实现。尝试使用以下方法。
在您的对话片段中:
public class YourDialogFragment : DialogFragment {
@Nullable private OnInputListener onInputListener;
public setInputListener(onInputListener : OnInputListener) {
this.onInputListener = onInputListener
}
//Other codes here
//Make sure to null check with this code before sending
// if (this.onInputListener != null) { onInputListener.doSth() }
@Override
public void onDestroy {
this.interfaceOnInputListener = null
super. onDestroy()
}
}
然后你可以在创建dialog fragment的时候通过暴露的方法来设置监听器,比如说你的activty中有这个功能
class YourActivity : AppCompatActivity {
public void showDialog() {
public final dialogFragment = YourDialogFragment()
dialogFragment.setInputListener(this) //this can be whatever interface implmenetation you want
dialogFragment.show(getSupportFragmentManager(), "TAG_HERE")
}
}
这样即使后面重构逻辑,也不用担心类型转换失败或者context为null。这种方法的另一个好处是片段不再依赖于它的调用者来实现接口,所以它也有利于以后的测试。
经过各种变通,问题终于解决了。但我有意更改它并在 Fragment A 上,在 ActivityResult 上得到它。
弹出对话框中的代码
Intent intent = new Intent();
intent.putExtra("class",spnSubClass.getSelectedItem().toString());
intent.putExtra("month",strSelectedMonth);
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
dismiss();
并在片段 A 中得到它:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case POPUPDIALOG:
if (resultCode == Activity.RESULT_OK) {
//--- get value from dialog
Bundle bundle = data.getExtras();
strClass = bundle.getString("class");
strMonth = bundle.getString("month");
} else if (resultCode == Activity.RESULT_CANCELED) {
//
}
break;
}
}
interfaceOnInputListener = (OnInputListener) getTargetFragment();
这是一个类似的程序。请参阅此以获得更多理解。