gpt4 book ai didi

java - 具有 fragment 的 Activity 可以获取两个不同的 fragment 并旋转设备

转载 作者:行者123 更新时间:2023-12-01 11:36:55 26 4
gpt4 key购买 nike

我对 android、java 等几乎都是新的,对fragment 也是新的。我有一个 Activity (A),它使用 fragment (B) 显示列表。选择此列表中的一项,同一 fragment 将更改为使用 fragment (C) 显示另一个列表。它可以工作,除非我在显示第二个列表(C)时旋转设备。此外,当显示第一个列表 (B) 时,如果我旋转设备,它会完美工作。

错误日志目录:

    04-26 11:30:32.769: E/AndroidRuntime(2882): FATAL EXCEPTION: main
04-26 11:30:32.769: E/AndroidRuntime(2882): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.traffic/com.example.traffic.ListTriplines}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.traffic.ListPoints: make sure class name exists, is public, and has an empty constructor that is public
(...)
04-26 11:30:32.769: E/AndroidRuntime(2882): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.traffic.ListPoints: make sure class name exists, is public, and has an empty constructor that is public
(...)
04-26 11:30:32.769: E/AndroidRuntime(2882): Caused by: java.lang.InstantiationException: com.example.traffic.ListPoints

Activity A(java + XML):

public class MainA extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_triplines);
}

@Override
public void onTripSelected(int cod) {
Fragment pointsFragment = new ListPoints(cod);
FragmentTransaction fTransaction = fManager.beginTransaction();
fTransaction.replace(R.id.trips_points_fragment, pointsFragment);
fTransaction.addToBackStack(null);
fTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fTransaction.commit();
}

@Override
public void onPointSelected(int pos) {
//do some stuff (using pos)
(...)
}
}



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<TextView
android:id="@+id/main_title"
style="@style/HelpTitle"
android:text="@string/listtrips_title"
/>

<fragment
android:id="@+id/trips_points_fragment"
android:name="com.example.traffic.FragmentB"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</RelativeLayout>

fragment B(java + XML):

(...)
import android.support.v4.app.Fragment;
(...)
public class FragmentB extends Fragment {

private OnTripSelectedListener tSelected;
private static ListTriplines listtriplines;
private Context context;
private LayoutInflater inflater;

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
//CHECK che nell'ACTIVITY sia IMPLEMENT il listener
try {
tSelected = (OnTripSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnTripSelectedListener");
}

listtrips = (ListTriplines) activity;
context = activity.getApplicationContext();
inflater = LayoutInflater.from(activity);
}

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup vG, Bundle savedInstanceState) {
//Inflate the layout for this fragment
final View viewResult = inflater.inflate(R.layout.list_trips, vG, false);

listview_trips = (ListView) viewResult.findViewById(R.id.trips_listview);

return viewResult;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

listAdapter = new CursorAdapter(...);

listview_trips.setAdapter(listAdapter);
listview_trips.setOnItemClickListener(onItemClickListener);
listview_trips.setOnItemLongClickListener(onItemLongClickListener);
}


public interface OnTripSelectedListener {
public void onTripSelected(int cod);
}

private OnItemClickListener onItemClickListener = new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
tSelected.onTripSelected(id);
}

};
}



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ExpandableListView
android:id="@+id/trips_explistview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/gray"
/>
</LinearLayout>

C fragment (java + XML):

(...)
import android.support.v4.app.Fragment;
(...)
public FragmentC extends Fragment {

private OnPointSelectedListener pListener;
private static ListTriplines listtrips;
private Context context;
private int cod;

public ListPoints (int _cod) {
this.cod = _cod;
}

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
pListener = (OnPointSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnPointSelectedListener");
}

listtrips = (ListTriplines) activity;
context = activity.getApplicationContext();
inflater = LayoutInflater.from(activity);
}

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup vG, Bundle savedInstanceState) {
//Inflate the layout for this fragment
final View viewResult = inflater.inflate(R.layout.list_points, vG/*null*/, false);

listview_points = (ListView) viewResult.findViewById(R.id.points_listview);

return viewResult;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

pointsAdapter = new CursorAdapter(...);
listview_points.setAdapter(pointsAdapter);
listview_points.setOnItemClickListener(onItemClickListener);

}

public interface OnPointSelectedListener {
public void onPointSelected(int pos);
}

private OnItemClickListener onItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
pListener.onPointSelected(pos);
}
};

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="@+id/points_listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/gray"
/>
</LinearLayout>

也许我的问题是因为我使用 1 个 fragment 来显示 2 个不同的 fragment ?在这种情况下,我使用 2 个 fragment 来解决它,并替换必须显示的 fragment (使用 VISIBILITY.GONE)?

谢谢

编辑:在 XML 主 Activity (A) 中,我更改了 fragment 名称 -> FragmentB (当我发布问题时我忘记更改它)。

注意:我需要对此进行下划线 -> 当 Activity (A) 启动时,它会加载 FragmentB (B);然后我选择一个项目并加载 FragmentC (C);当我在 XML 中旋转时,有 FragmentB(显然),而 Activity (A) 必须加载 FragmentC (C)。不知道Android是否可以处理这种情况。

<小时/>

解决方法:

1) Ortsinton 修改后的 LogCat(创建一个空构造函数,并使用“BUNDLE”传递一些参数):

04-26 14:24:46.809: E/AndroidRuntime(11558): FATAL EXCEPTION: main
04-26 14:24:46.809: E/AndroidRuntime(11558): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.traffic/com.example.traffic.ListTriplines}: android.view.InflateException: Binary XML file line #23: Error inflating class fragment
04-26 14:24:46.809: E/AndroidRuntime(11558): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1659)
(...)
04-26 14:24:46.809: E/AndroidRuntime(11558): Caused by: android.view.InflateException: Binary XML file line #23: Error inflating class fragment
(...)
04-26 14:24:46.809: E/AndroidRuntime(11558): Caused by: java.lang.IllegalStateException: Fragment com.example.traffic.ListTrips did not create a view.

2) 以编程方式实例化 Fragment(不是通过 XML):- 在 XML 中,您必须使用“布局”(我使用 FrameLayout)而不是“fragment ”;- 在java脚本中,必须使用“FragmentTransaction”;

3) Android 会处理 Activity(包含 fragment ),并且 Android 会按照开始时的状态重新创建它,因此您必须实现 onSaveInstanceState(保存数据)和 onRestoreInstanceState(修改 Activity)就像旋转设备时一样)。

最佳答案

我认为你的错误就在这里,在ListPoints Fragment中:

 public ListPoints (int _cod) {
this.cod = _cod;
}

来自Fragment class reference by Android

All subclasses of Fragment must include a public no-argument constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it. If the no-argument constructor is not available, a runtime exception will occur in some cases during state restore.

fragment 需要一个空的构造函数,以便可以实例化它,但不能覆盖它。因此,如果您需要向其传递一些参数,请尝试以下操作:

在 Activity 中写入:

Bundle bundle = new Bundle();
bundle.putInt(key, _cod);
fragment.setArguments(bundle);

读取 fragment :

Bundle arguments = this.getArguments();
this.cod = arguments.getInt(key);

不要忘记重写 onSaveInstanceState 函数,这样如果应用程序处于后台并被终止,它将能够正确恢复状态。否则你的变量将没有值(value)

关于java - 具有 fragment 的 Activity 可以获取两个不同的 fragment 并旋转设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29876173/

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