[英]Android Listview in Baseadapter how can I save changes to the list
[英]How can I add child fragments to a fragment in Android using a BaseAdapter
此圖說明了我的活動的復雜性。 有多層(在這種情況下為3層)片段需要動態加載。 重復的片段使用LinearListView加載,我在這里找到了一個視圖庫: 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使用適配器加載片段(此代碼中的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方法應加載下一級子片段,但是我嘗試過的所有方法均無效。 看來布局還沒有膨脹,因此我無法為其添加子視圖。
我的問題是,“如何從getView中添加子片段?” 也許我正在解決這個錯誤。
這是我嘗試過的一個示例:
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添加片段,即:
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" />
最后,我為此目的離開了碎片,並刪除了通貨膨脹代碼。 取而代之的是,我使用xml中的include加載相同的布局結構,因此我不必構建比已有的更大的xml文件。
對於本應放在片段中的功能,我將其放置在presenter類中,然后使用來自ButterKnife的視圖注入將presenter綁定到視圖中的適當級別。
我仍在使用事件總線在@ 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綁定到視圖的該部分:
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;
}
}
這個例子有點不完整,我還沒有一個示例項目,但是希望它能對某人有所幫助。 它不能按預期方式回答問題,但是經過兩種方式的嘗試,我認為這是一個更好的解決方案,因為它比處理片段的復雜性要簡單。 片段仍將用於更改屏幕尺寸/方向,但片段將不用於復雜的布局。 感謝您的任何意見。
對適配器使用不同的類
public class TabCategory extends Fragment { private ListView listView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View tabCat=inflater.inflate(R.layout.tab_all, container, false); listView = (ListView) tabCat.findViewById(R.id.listView); //ADAPTER CategoryList adapter = new CategoryList(getContext()); listView.setAdapter(adapter); return tabCat; } }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.