使用片段为Android应用程序更正模式

时间:2014-08-31 10:53:02

标签: android design-patterns android-fragments android-fragmentactivity

我目前正在开发一个简单的Android应用程序,它基本上是一个项目列表,点击时会显示第二个带有详细信息的屏幕。

以下是应用层次结构:

---> MainActivity.java
   --> MyListFragment.java
   --> MyDetailFragment.java

因此,当打开应用程序时,列表将通过MyListFragment.java显示,当单击某个项目时,项目位置将传递到MyDetailFragment.java,并替换该片段以显示该项目的详细信息。

目前我尝试在加载MyDetailFragment.java时实现一个向上插入按钮,但当用户按下“后退”或使用向上插入按钮时,当MyListFragment.java也被加载时,出现了诸如up插入符号出现的错误

在线研究问题后,我发现有些用户使用单独的活动以及如下所示的片段:

---> MainListActivity.java
  --> MyListFragment.java
---> DetailListActivity.java
  --> MyDetailFragment.java

我的问题:哪种模式更好用,第一种或第二种以及为什么?

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

根据您的上一条评论,您可能需要使用标记添加片段,例如" ListFragment",并在活动检查中是否可见片段:

Fragment fragment = getFragmentManager().findFragmentByTag("ListFragment"); 
if (fragment != null && fragment.isAdded() && fragment.isVisible()) {
     getActionBar().setDisplayHomeAsUpEnabled(true); 
} else {
     getActionBar().setDisplayHomeAsUpEnabled(false); 
}

这可以在活动的onResume或onCreateOptionsMenu中完成。

对片段使用setHasOptionsMenu(true)允许片段添加属于片段的更多选项菜单项。但既然你在打电话:

getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);

我相信setHasOptionsMenu(true)在这种情况下没有效果,因为您直接与Activity对话。这也是为什么删除片段不会更改/删除向上插入符号的原因。

另一种可能的解决方案是在碎片被分离时手动移除向上插入符号。

public void onDetach () {
    getActivity().getActionBar().setDisplayHomeAsUpEnabled(false);
    getActivity().invalidateOptionsMenu(); // <- not sure if needed
}

好的,现在我查看了你的代码。以下是我的建议:

请注意,我没有测试过此代码并且是用记事本编写的,因此可能包含一些拼写错误。

<强> MainActivity: 将up插入符号移动到Activity(对于片段,setOptionsMenu(true)无论如何都不会处理此问题)。

public class MainActivity extends Activity {
    private static final String DB_NAME = "hisnul.sqlite3";

    //A good practice is to define database field names as constants
    private static final String TABLE_NAME = "en_dua";
    private static final String DUA_ID = "_id";
    private static final String DUA_TITLE = "title";

    private SQLiteDatabase database;
    private ArrayList duas;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FragmentDuaList())
                    .commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_activity_dualist, menu);
        restoreActionBar();
        return true;
    }

    private void restoreActionBar() {
        Fragment detailFragment = getFragmentManager().findFragmentByTag("DetailListFragment");
        if (detailFragment != null) {
            // means a detail fragment has been added and we need the up caret
            getActionBar().setDisplayHomeAsUpEnabled(true);
        } else {
            getActionBar().setDisplayHomeAsUpEnabled(false);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        // why not use switch case here?
        if(id == android.R.id.home) {
                Toast.makeText(this, "Test Caret", Toast.LENGTH_SHORT).show();
                getFragmentManager().popBackStack();
                Log.d("Khalid", "Testing CARET");
                return true;
        } if (id == R.id.action_settings) {
            Toast.makeText(this,"Settings Clicked", Toast.LENGTH_SHORT).show();
            return true;
        }
        else if (id == R.id.action_bookmarks){
            Toast.makeText(this,"Favorites Clicked", Toast.LENGTH_SHORT).show();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_dua_list, container, false);
        }
    }
}

<强> FragmentDuaList: 这里没有变化

<强> FragmentDuaDetail: 删除ActionBar代码:

public class FragmentDuaDetail extends Fragment {

    private static final String DB_NAME = "hisnul.sqlite3";

    //A good practice is to define database field names as constants
    private static final String TABLE_NAME = "en_dua";
    private static final String DUA_ID = "_id";
    private static final String DUA_TITLE = "title";

    private static final String DUA_ARABIC = "arabic";
    private static final String DUA_TRANSLATION = "translation";
    private static final String DUA_REFERENCE = "reference";

    private String title;
    private String arabic;
    private String translation;
    private String reference;

    private String dua_from_list_fragment;

    private SQLiteDatabase database;
    private ArrayList duaDetails;

    private View rootView;

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

        // Inflate the layout for this fragment
        rootView = inflater.inflate(R.layout.fragment_dua_detail, container, false);

        dua_from_list_fragment = getArguments().getString("dua_id");

        //Our key helper
        ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(getActivity(), DB_NAME);
        database = dbOpenHelper.openDataBase();
        //That’s it, the database is open!
        fillDua();
        setUpDuaList();

        getActivity().invalidateOptionsMenu();

        return rootView;
    }

    public void fillDua(){
        //Extracting Elements from Database
        duaDetails = new ArrayList<DuaDetail>();
        Cursor friendCursor = database.query(TABLE_NAME, new String[] {DUA_TITLE,
                DUA_ARABIC, DUA_TRANSLATION, DUA_REFERENCE}, DUA_ID + "=" + dua_from_list_fragment, null, null, null, null);
        friendCursor.moveToFirst();
        if(!friendCursor.isAfterLast()) {
            do {
                title = friendCursor.getString(0);
                arabic = friendCursor.getString(1);
                translation = friendCursor.getString(2);
                reference = friendCursor.getString(3);
                duaDetails.add(new DuaDetail(title, arabic, translation, reference));
            } while (friendCursor.moveToNext());
        }
        friendCursor.close();
    }

    public void setUpDuaList(){
        TextView tvDuaTitle = (TextView) rootView.findViewById(R.id.txtDuaTitle);
        TextView tvDuaArabic = (TextView) rootView.findViewById(R.id.txtDuaArabic);
        TextView tvDuaTranslation = (TextView) rootView.findViewById(R.id.txtDuaTranslation);
        TextView tvDuaReference = (TextView) rootView.findViewById(R.id.txtDuaReference);

        Typeface face;
        face = Typeface.createFromAsset(getActivity().getAssets(), "DroidNaskh-Regular.ttf");
        tvDuaArabic.setTypeface(face);

        tvDuaTitle.setText(title);
        tvDuaArabic.setText(arabic);
        tvDuaTranslation.setText(translation);
        tvDuaReference.setText(reference);
    }


}