gpt4 book ai didi

java - 如何使用 BaseAdapter 将子 fragment 添加到 Android 中的 fragment

转载 作者:太空宇宙 更新时间:2023-11-04 12:55:16 27 4
gpt4 key购买 nike

Diagram of Hierarchical View consisting of Android Activity with Fragments

此图说明了我的 Activity 的复杂性。有多个(本例中为 3 层) fragment 需要动态加载。重复 fragment 是使用 LinearListView 加载的,这是我在这里找到的一个 View 库:https://github.com/frankiesardo/LinearListView 。这允许列表像 ListView 一样加载,但避免了在 ScrollView 中包含 ListView 的问题。

以下是一些示例代码:

line_item_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/line_item_list">

<TextView
android:layout_width="171dp"
android:layout_height="wrap_content"
android:text="LineItem List"
android:id="@+id/line_item_list_text" />

<com.linearlistview.LinearListView
android:id="@+id/line_item_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#f00"
android:orientation="vertical"
android:showDividers="middle"
app:dividerThickness="16dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"/>
</LinearLayout>

line_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/line_item">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="my line item."
android:id="@+id/line_item_text"
android:layout_gravity="center_horizontal" />

<!-- notes child items go here -->

</LinearLayout>

LineItemFragment.java 使用适配器加载 fragment (此代码中的 lineItem 在上图中显示为“Part”一词。)

public class LineItemFragment extends Fragment {
LineItemAdapter adapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {


LinearListView lineItems = (LinearListView)container.findViewById(R.id.line_item_wrapper);
adapter = new LineItemAdapter(this.getContext(), getChildFragmentManager());
lineItems.setAdapter(adapter);

return null;

}
}

LineItemAdapter.java

public class LineItemAdapter extends BaseAdapter{

ArrayList<String> lineItems = new ArrayList<String>();
Context context;
FragmentManager fm;


public LineItemAdapter(Context context, FragmentManager fragmentManager) {
this.context = context;
lineItems.add("Item A");
lineItems.add("Item B");
lineItems.add("Item C");
this.fm = fragmentManager;
}

@Override
public int getCount() {
return lineItems.size();
}

@Override
public Object getItem(int position) {
return lineItems.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = ((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.line_item, parent, false);
}
((TextView)convertView.findViewById(R.id.line_item_text)).setText(getItem(position).toString());


// *** The getView method could load the child fragments
return convertView;
}
}

在上一个文件(***)中,我当前认为 getView 方法应该加载下一级子 fragment ,但我尝试过的一切都不起作用。布局似乎尚未膨胀,因此我无法向其中添加 subview 。

我的问题是,“如何从 getView 中添加子 fragment ?”或者也许我的做法是错误的。

这是我尝试过的一个示例:

lineItemAdapter.java 中的 getView 方法(***):

.
.
.

LinearLayout notes = (LinearLayout) ((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.line_item, parent, false);

LinearLayout b = (LinearLayout)((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.note_list, notes).getRootView();

NoteListFragment noteListFragment = new NoteListFragment();
fm.beginTransaction().add(b.getId(), noteListFragment).commit();
.
.
.

我遇到了这样的异常。

E/AndroidRuntime: FATAL EXCEPTION: main

Process: com.example.myapplication, PID: 12207

java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.myapplication/com.example.myapplication.DetailActivity}: java.lang.IllegalStateException: Fragment does not have a view
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
.
.
.

提前致谢。

编辑

我需要在 xml 中添加一个 fragment 吗,即:

line_item.xml...新节点:

<fragment android:name="com.example.noteListFragment"
android:id="@+id/note_list_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />

最佳答案

最后,我出于此目的放弃了 fragment ,并删除了通货膨胀代码。相反,我加载包含在 xml 中的相同布局结构,因此我不必构建比已有的更大的 xml 文件。

对于我要放入 fragment 中的功能,我放入了演示者类,然后使用 ButterKnife 的 View 注入(inject)将演示者绑定(bind)到 View 中的适当级别。

我仍在研究使用事件总线在各层之间进行通信,如 @mt0s 建议的那样。

如果您想朝这个方向发展,这里有一些代码可以帮助您:

使用 include,我可以将整个结构整合在一起,将每个层布局保留在自己的 xml 文件中:

<LinearLayout 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:id="@+id/activity_workorder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
>
<LinearLayout
android:id="@+id/workorder_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/workorder_header"/> <!-- include other layouts -->
<include layout="@layout/workorder_service_items"/>
</LinearLayout>
</LinearLayout>

接下来,我创建了一个 Presenter.class 文件来设置适配器,使用 ButterKnife 绑定(bind)到 View 的该部分:

public class WorkOrderPresenter implements PropertyChangeListener
{

private View detailView;
private WorkOrder workOrder; // the object to display
private List<WorkorderAsset> assetList;

// Set your bindings to the view, passing the id from the layout.
@Bind(R.id.workorderasset_list) View serviceItemDetail;
@Bind(R.id.workorderasset_list_content) LinearListView assets;
@Bind(R.id.number_of_service_items) TextView numberOfServiceItems;
@Bind(R.id.total_value) TextView totalView;

WorkOrderAssetAdapter workOrderAssetAdapter; // an adapter for a child list

// Constructor
public WorkOrderPresenter(View view, WorkOrder wo, final Activity activity)
{
workOrder = wo;
detailView = view;
ButterKnife.bind(this, detailView); //this is where the binding actually happens

workOrderAssetContent = Provider.GetItems // Load you items for the adapter.

// My system gives items back asynchronously:
workOrderAssetContent.getWorkOrderAssets(workOrder.getWorkOrderID(), new iProvideCallback<List<WorkorderAsset>>() {
@Override
public void onSuccess(iResponse<List<WorkorderAsset>> response) {
assetList = response.getResponse();
numberOfServiceItems.setText(String.valueOf(assetList.size()));
workOrderAssetAdapter = new WorkOrderAssetAdapter(activity, assetList); // construct the adapter with items.
assets.setAdapter(workOrderAssetAdapter);
}

@Override
public void onFailure(iResponse<List<WorkorderAsset>> response) {
Toast.makeText(activity.getApplicationContext(), R.string.ServiceItemsError, Toast.LENGTH_LONG);

}
});
}
}

这是一个用于显示项目的适配器:

public class WorkOrderAssetAdapter extends BaseAdapter
{
private Activity activity;
private List<WorkorderAsset> workorderAssetList;
private static LayoutInflater inflater = null;

// Constructor
public WorkOrderAssetAdapter(Activity a, List<WorkorderAsset> items)
{
workorderAssetList = items;
activity = a;
inflater = LayoutInflater.from(activity);
}

@Override
public int getCount() { return workorderAssetList.size(); }

@Override
public Object getItem(int position) { return workorderAssetList.get(position); }

@Override
public long getItemId(int position) { return position; }

// view holder for the item
public static class ViewHolder extends WorkOrderAssetViewHolder
{
@Bind(R.id.line_item_text) TextView line_item_text;
@Bind(R.id.line_item_list) LinearListView list;

// Adapter, Data Provider and Presenter for the next level.
public WorkOrderAssetLineItemAdapter adapter;
public WorkOrderAssetLineItemProvider provider;
public WorkOrderAssetLineItemPresenter presenter;

private Activity activity;
private WorkorderAsset workOrderAsset;

public VehicleViewHolder(WorkorderAsset asset, final View view, Activity activity_in)
{
ButterKnife.bind(this, view);
workOrderAsset = asset;
activity = activity_in;
workOrderAssetLineItemContent = new WorkOrderAssetLineItemContent(((RoadFS)activity.getApplication()).getServer(), ((RoadFS)activity.getApplication()).getApplicationContext());
workOrderAssetLineItemContent.getWorkOrderAssetLineItems(
workOrderAsset.getWorkOrderID(),
workOrderAsset.getWorkOrderAssetID(),
new iProvideCallback<List<WorkorderAssetLineItem>>() {

@Override
public void onSuccess(iResponse response) {
list.setAdapter(new WorkOrderAssetLineItemAdapter(activity,
(List<WorkorderAssetLineItem>) response.getResponse(),
view));
}

@Override
public void onFailure(iResponse response) {

}
});

}

@Override
public View getView(final int position, View view, ViewGroup parent)
{

WorkorderAsset workOrderAsset;
workOrderAsset = workorderAssetList.get(position);
ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
} else {
view = inflater.inflate(R.layout.workorder_detail_workorderasset_vehicle, parent, false);
holder = new VehicleViewHolder(workOrderAsset, view, activity);
view.setTag(holder);
}

holder.item_text.setText(workOrderAsset.getVIN());

holder.workOrderAssetLineItemContent = new WorkOrderAssetLineItemContent(((RoadFS) activity.getApplication()).getServer(), activity);
holder.workOrderAssetLineItemAdapter = new WorkOrderAssetLineItemAdapter(activity, WorkOrderAssetLineItemContent.workorderAssetLineItemList, view);

return view;
}
}

这个例子有点不完整,我还没有示例项目,但希望它能帮助别人。它没有按预期回答问题,但尝试了两种方法后,我认为这是一个更好的解决方案,因为它比处理 fragment 的复杂性更简单。 fragment 仍将用于更改屏幕大小/方向,但 fragment 不会用于复杂的布局。感谢您的任何意见。

关于java - 如何使用 BaseAdapter 将子 fragment 添加到 Android 中的 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35448844/

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