gpt4 book ai didi

android - 坚持从 Activity 移植到 fragment

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:06:10 45 4
gpt4 key购买 nike

我尝试将一个简单的基于 Activity 的应用程序移植到 fragment 中已经整整一周了。我完全卡住了。

这个野兽是一个简单的列表、详细信息、添加/编辑应用程序,带有上下文菜单和选项菜单。我试图做到正确: fragment 和 Activity 各自在自己的文件中,使用手机和平板电脑的 v4 支持包, fragment 完成了可重用 fragment 应该做的一切,回调(很多)飞来飞去通知 Activity 和关于该做什么的 fragment 。从 SQLiteOpenHelper 转换为 ContentProvider,从 optionmenu 转换为 actionbarmenu,以及,和,以及,……(我使用的几乎所有内容现在都已弃用)。

太可怕了。我的基于 Activity 的简单小型工作应用程序现在的大小几乎是原来的 3 倍,而且很多东西还不能正常工作。

如果需要,我可以在此处添加我的代码 - 但它有很多东西(您已被警告)。

我的问题:是否有人愿意分享一个包含列表、详细信息添加/编辑的完整示例?此示例应为 Fragments 和 Activity 使用单独的文件(而不是来自 Google 的一体化包)。

请不要投反对票。我真的很想看看如何使它正确。

非常感谢。

编辑:

这是开始 Activity ,它有两种布局(res/layout 用于手机,res/layout-large-land 用于平板电脑)和上下文菜单:

public class ActivityList extends FragmentActivity implements FragmentList.MyContextItemSelectedListener,
FragmentList.MyDeleteListener,
FragmentList.MyListItemClickListener,
FragmentList.MyOptionsItemSelectedListener,
FragmentDetails.MyDeleteListener,
FragmentDetails.MyOptionsItemSelectedListener {

@Override
public void myContextItemSelected(final int action, final long id) {
if (action == R.id.men_add) {
processEdit(0);
} else if (action == R.id.men_delete) {
processUpdateList();
} else if (action == R.id.men_details) {
processDetails(id);
} else if (action == R.id.men_edit) {
processEdit(id);
}
}

@Override
public void myDelete(final long id) {
processUpdateList();
}

@Override
public void myListItemClick(final long id) {
processDetails(id);
}

@Override
public void myOptionsItemSelected(final int action) {
myOptionsItemSelected(action, 0);
}

@Override
public void myOptionsItemSelected(final int action, final long id) {
if (action == R.id.men_add) {
processEdit(0);
} else if (action == R.id.men_edit) {
processEdit(id);
} else if (action == R.id.men_preferences) {
processPreferences();
}
}

@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
processUpdateList();
}

@Override
public void onCreate(final Bundle bundle) {
super.onCreate(bundle);

setContentView(R.layout.activitylist);
}

private void processEdit(final long id) {
Intent intent = new Intent(this, ActivityEdit.class);
intent.putExtra("ID", id);
startActivityForResult(intent, MyConstants.DLG_TABLE1EDIT);
}

private void processDetails(final long id) {
if (Tools.isXlargeLand(getApplicationContext())) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.right);
if (fragment == null ||
(fragment instanceof FragmentDetails && ((FragmentDetails) fragment).getCurrentId() != id)) {
fragment = new FragmentDetails(id);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.right, fragment);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
}
} else {
Intent intent = new Intent(this, ActivityDetails.class);
intent.putExtra("ID", id);
startActivityForResult(intent, MyConstants.DLG_TABLE1SHOW);
}
}

private void processPreferences() {
Intent intent = new Intent(this, MyPreferenceActivity.class);
startActivityForResult(intent, MyConstants.DLG_PREFERENCES);
}

private void processUpdateList() {
// TODO:
}
}

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

<fragment
class="com.test.app.FragmentList"
android:id="@+id/fragmentlist"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:name="com.test.app.FragmentList" />
</LinearLayout>

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

<fragment
class="com.test.app.FragmentList"
android:id="@+id/fragmentlist"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0dip"
android:name="com.test.app.FragmentList" />

<FrameLayout
android:id="@+id/right"
android:layout_height="match_parent"
android:layout_weight="2"
android:layout_width="0dip" />
</LinearLayout>

这是带有行布局、选项菜单和上下文菜单的 ListFragment:

public class FragmentList extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

private SimpleCursorAdapter adapter;
private AlertDialog alertDialog;
private Context context;
private MyContextItemSelectedListener contextItemSelectedListener;
private MyDeleteListener deleteListener;
private long id;
private MyListItemClickListener listItemClickListener;
private ListView listView;
private MyOptionsItemSelectedListener optionsItemSelectedListener;

public interface MyContextItemSelectedListener {
public void myContextItemSelected(int action, long id);
}

public interface MyDeleteListener {
public void myDelete(long id);
}

public interface MyListItemClickListener {
public void myListItemClick(long id);
}

public interface MyOptionsItemSelectedListener {
public void myOptionsItemSelected(int action);
}

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

context = getActivity().getApplicationContext();

listView = getListView();

getActivity().getSupportLoaderManager().initLoader(MyConstants.LDR_TABLE1LIST, null, this);

adapter = new SimpleCursorAdapter(context,
R.layout.fragmentlist_row,
null,
new String[] { Table1.DESCRIPTION },
new int[] { R.id.fragmentlist_row_description },
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(adapter);
setListShown(false);

registerForContextMenu(listView);

if (bundle != null && bundle.containsKey("ID")) {
id = bundle.getLong("ID");
listItemClickListener.myListItemClick(id);
}

if (Tools.isXlargeLand(context)) {
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}

setHasOptionsMenu(true);
}

@Override
public void onAttach(final Activity activity) {
super.onAttach(activity);

// Reduced: Check for implemented listeners
}

@Override
public boolean onContextItemSelected(final MenuItem menuItem) {
AdapterContextMenuInfo adapterContextMenuInfo = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();

final long id = adapterContextMenuInfo.id;

if (menuItem.getItemId() == R.id.men_delete) {
processAlertDialog(id);
return true;
} else {
contextItemSelectedListener.myContextItemSelected(menuItem.getItemId(), adapterContextMenuInfo.id);
}

return super.onContextItemSelected(menuItem);
}

@Override
public void onCreateContextMenu(final ContextMenu contextMenu, final View view, final ContextMenuInfo contextMenuInfo) {
super.onCreateContextMenu(contextMenu, view, contextMenuInfo);

if (view.getId() == android.R.id.list) {
getActivity().getMenuInflater().inflate(R.menu.fragmentlist_context, contextMenu);
}
}

@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle bundle) {
MyCursorLoader loader = null;

switch (id) {
case MyConstants.LDR_TABLE1LIST:
loader = new MyCursorLoader(context,
MySQLiteOpenHelper.TABLE1_FETCH,
null);
break;
}

return loader;
}

@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater menuInflater) {
super.onCreateOptionsMenu(menu, menuInflater);

menu.clear();

menuInflater.inflate(R.menu.fragmentlist, menu);
}

@Override
public void onListItemClick(final ListView listView, final View view, final int position, final long id) {
super.onListItemClick(listView, view, position, id);

this.id = id;

if (Tools.isXlargeLand(context)) {
listView.setItemChecked(position, true);
}

listItemClickListener.myListItemClick(id);
}

@Override
public void onLoaderReset(final Loader<Cursor> loader) {
adapter.swapCursor(null);
}

@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
adapter.swapCursor(cursor);

setListShown(true);
}

@Override
public boolean onOptionsItemSelected(final MenuItem menuItem) {
optionsItemSelectedListener.myOptionsItemSelected(menuItem.getItemId());

return super.onOptionsItemSelected(menuItem);
}

@Override
public void onSaveInstanceState(final Bundle bundle) {
super.onSaveInstanceState(bundle);

bundle.putLong("ID", id);
}

private void processAlertDialog(final long id) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

@Override
public void onClick(final DialogInterface dialogInterface, final int which) {
dialogInterface.dismiss();
}
} );
alertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

@Override
public void onClick(final DialogInterface dialogInterface, final int which) {
MyApplication.getSqliteOpenHelper().deleteTable1(id);

alertDialog.dismiss();

deleteListener.myDelete(id);
}
} );
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setMessage(R.string.txt_reallydelete);

alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:paddingBottom="2dip"
android:paddingTop="2dip" >

<TextView
style="@style/TextViewLarge"
android:id="@+id/fragmentlist_row_description"
android:textStyle="bold" />
</LinearLayout>


<menu
xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:icon="@drawable/ic_menu_add"
android:id="@+id/men_add"
android:showAsAction="ifRoom|withText"
android:title="@string/txt_add" />

<item
android:icon="@drawable/ic_menu_preferences"
android:id="@+id/men_preferences"
android:showAsAction="ifRoom|withText"
android:title="@string/txt_preferences" />
</menu>

<menu
xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:id="@+id/men_details"
android:title="@string/txt_details" />

<item
android:id="@+id/men_edit"
android:title="@string/txt_edit" />

<item
android:id="@+id/men_delete"
android:title="@string/txt_delete" />
</menu>

这是 DetailsActivity:

public class ActivityDetails extends FragmentActivity implements FragmentDetails.MyDeleteListener, 
FragmentDetails.MyOptionsItemSelectedListener {

private long id;

@Override
public void myDelete(final long id) {
setResult(RESULT_OK);
finish();
}

@Override
public void myOptionsItemSelected(final int action, final long id) {
if (action == R.id.men_add) {
processEdit(0);
} else if (action == R.id.men_edit) {
processEdit(id);
} else if (action == R.id.men_preferences) {
processPreferences();
}
}

@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
if (requestCode == MyConstants.DLG_PREFERENCES || requestCode == MyConstants.DLG_TABLE1EDIT) {
finish();

startActivity(getIntent());
}
}

@Override
protected void onCreate(final Bundle bundle) {
super.onCreate(bundle);

if (bundle != null) {
if (bundle.containsKey("ID")) {
id = bundle.getLong("ID");
}
} else {
Bundle bundleExtras = getIntent().getExtras();
if (bundleExtras != null) {
id = bundleExtras.getLong("ID");
}

processDetails(id);
}
}

@Override
public void onSaveInstanceState(final Bundle bundle) {
super.onSaveInstanceState(bundle);

bundle.putLong("ID", id);
}

private void processDetails(final long id) {
FragmentDetails fragment = new FragmentDetails(id);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, fragment);
transaction.commit();
}

private void processEdit(final long id) {
Intent intent = new Intent(this, ActivityEdit.class);
intent.putExtra("ID", id);
startActivityForResult(intent, MyConstants.DLG_TABLE1EDIT);
}

private void processPreferences() {
Intent intent = new Intent(this, MyPreferenceActivity.class);
startActivityForResult(intent, MyConstants.DLG_PREFERENCES);
}
}

这是带有布局和菜单的 DetailsFragment:

public class FragmentDetails extends Fragment {

private AlertDialog alertDialog;
private MyDeleteListener deleteListener;
private long id;
private MyOptionsItemSelectedListener optionsItemSelectedListener;
private TextView textViewDescription;
private TextView textViewId;

public FragmentDetails() {
id = 0;
}

public FragmentDetails(final long id) {
this.id = id;
}

public long getCurrentId() {
return id;
}

public interface MyDeleteListener {
public void myDelete(long id);
}

public interface MyOptionsItemSelectedListener {
public void myOptionsItemSelected(int action, long id);
}

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

if (bundle != null && bundle.containsKey("ID")) {
id = bundle.getLong("ID");
}

setHasOptionsMenu(true);
}

@Override
public void onAttach(final Activity activity) {
super.onAttach(activity);

// Reduced
}

@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater menuInflater) {
super.onCreateOptionsMenu(menu, menuInflater);

menu.clear();

menuInflater.inflate(R.menu.fragmentdetails, menu);
}

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup viewGroup, final Bundle bundle) {
View view = inflater.inflate(R.layout.fragmentdetails, null);

textViewDescription = (TextView) view.findViewById(R.id.tv_description);
textViewId = (TextView) view.findViewById(R.id.tv_id);

if (id != 0) {
Table1 table1;
if ((table1 = MyApplication.getSqliteOpenHelper().getTable1(id)) != null) {
textViewDescription.setText(Tools.defaultString(table1.getDescription()));
textViewId.setText(Tools.defaultString(String.valueOf(table1.getId())));
}
}

return view;
}

@Override
public boolean onOptionsItemSelected(final MenuItem menuItem) {
if (menuItem.getItemId() == R.id.men_delete) {
processAlertDialog(id);
return true;
} else {
optionsItemSelectedListener.myOptionsItemSelected(menuItem.getItemId(), id);
}

return super.onOptionsItemSelected(menuItem);
}

@Override
public void onSaveInstanceState(final Bundle bundle) {
super.onSaveInstanceState(bundle);

bundle.putLong("ID", id);
}

private void processAlertDialog(final long id) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

@Override
public void onClick(final DialogInterface dialogInterface, final int which) {
alertDialog.dismiss();
alertDialog = null;
}
} );
alertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

@Override
public void onClick(final DialogInterface dialogInterface, final int which) {
MyApplication.getSqliteOpenHelper().deleteTable1(id);

alertDialog.dismiss();
alertDialog = null;

deleteListener.myDelete(id);
}
} );
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setMessage(R.string.txt_reallydelete);

alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal" >

<TextView
style="@style/TextViewStandard"
android:layout_weight="1"
android:text="@string/txt_id" />

<TextView
style="@style/TextViewStandard"
android:id="@+id/tv_id"
android:layout_weight="1" />
</LinearLayout>

<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal" >

<TextView
style="@style/TextViewStandard"
android:layout_weight="1"
android:text="@string/txt_description" />

<TextView
style="@style/TextViewStandard"
android:id="@+id/tv_description"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>

<menu
xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:icon="@drawable/ic_menu_add"
android:id="@+id/men_add"
android:showAsAction="ifRoom|withText"
android:title="@string/txt_add" />

<item
android:icon="@drawable/ic_menu_edit"
android:id="@+id/men_edit"
android:showAsAction="ifRoom|withText"
android:title="@string/txt_edit" />

<item
android:icon="@drawable/ic_menu_delete"
android:id="@+id/men_delete"
android:showAsAction="ifRoom|withText"
android:title="@string/txt_delete" />

<item
android:icon="@drawable/ic_menu_preferences"
android:id="@+id/men_preferences"
android:showAsAction="ifRoom|withText"
android:title="@string/txt_preferences" />
</menu>

我没有发布 EditActivity,因为它只是一个没有 Fragment 的 FragmentActivity。

最佳答案

这可能不是全部答案,而是部分答案:您仍然有一个主要 Activity ,在您曾经有 ListView 的 xml 中,您现在添加了一个框架布局。然后在您的 oncreate Activity 中添加以下内容:

        mMainFragment = new ListFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.center_container, mMainFragment);

fragmentTransaction.commit();
mCurrentFragment = mMainFragment;

在你的列表 fragment 中

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// setup view
View view = inflater.inflate(R.layout.calendar_list, null);

mListAdapter = new CustomAdapter(getActivity(), R.layout.calendar_row, (ArrayList<Item>) mFullList);
setListAdapter(mListAdapter);

return view;
}

列表 fragment 的 XML:

<somelayout>
<ListView android:id="@id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</somelayout>

点击列表在 fragment 中触发:

@Override
public void onListItemClick(ListView list, View view, int position, long id) {
final Item item = (Item) list.getAdapter().getItem(position);
mListener.OnListClick(item);
}

它使用这个监听器:

公共(public)接口(interface) OnListItemClickListener { public void OnListClick(Item item);

Listfragment 需要将其置于顶部:

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

然后主 Activity 通过实现接口(interface)订阅此内容,并在触发监听器时启动详细信息 fragment 。

编辑:好的,所以你的问题要基本得多:)记住 oncreate 每次旋转时都会在你的 Activity 中调用,所以你的 Activity 需要记住要显示哪个 fragment ,就像它需要记住要显示哪个 View 一样。您还需要将 fragment 添加到返回堆栈,否则返回键将无法使用它们。将 fragment 视为具有功能的 View ,它们不是 Activity 。

关于android - 坚持从 Activity 移植到 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10013023/

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