我有两个片段,让我们称它们为片段A和片段B,它们是NavigationDrawer的一部分(这是它们所绑定的活动)。在片段A我有一个按钮。按下此按钮时,我希望将另一个项目添加到片段B中的ListView。
最好的方法是什么?使用Intents,SavedPreferences,公开(?)或其他东西?
编辑5:20/7/13这是与srains最新代码
这是我用来启动片段的NavigationDrawer
:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Navigation_Drawer extends FragmentActivity {
public DrawerLayout mDrawerLayout; // Creates a DrawerLayout called_.
public ListView mDrawerList;
public ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mNoterActivities; // This creates a string array called _.
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
// Just setting up the navigation drawer
} // End of onCreate
// Removed the menu
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
private void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (position == 0) {
Fragment qnfragment = new QuickNoteFragment();
((FragmentBase) qnfragment).setContext(this);
Bundle args = new Bundle(); // Creates a bundle called args
args.putInt(QuickNoteFragment.ARG_nOTERACTIVITY_NUMBER, position);
qnfragment.setArguments(args);
fragmentManager.beginTransaction()
.replace(R.id.content_frame, qnfragment).commit();
} else if (position == 3) {
Fragment pendViewPager = new PendViewPager(); // This is a ViewPager that includes HistoryFragment
((FragmentBase) pendViewPager).setContext(this);
Bundle args = new Bundle();
pendViewPager.setArguments(args);
fragmentManager.beginTransaction()
.replace(R.id.content_frame, pendViewPager).commit();
}
// Update title etc
}
@Override
protected void onPostCreate(Bundle savedInstanceState) { // Used for the NavDrawer toggle
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) { // Used for the NavDrawer toggle
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggles
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
这是QuickNoteFragment:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class QuickNoteFragment extends FragmentBase implements OnClickListener {
public static final String ARG_nOTERACTIVITY_NUMBER = "noter_activity";
Button b_create;
// removed other defining stuff
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.quicknote, container, false);
int i = getArguments().getInt(ARG_nOTERACTIVITY_NUMBER);
String noter_activity = getResources().getStringArray(
R.array.noter_array)[i];
FragmentManager fm = getFragmentManager();
setRetainInstance(true);
b_create = (Button) rootView.findViewById(R.id.qn_b_create);
// Removed other stuff
getActivity().setTitle(noter_activity);
return rootView;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.qn_b_create:
String data = "String data";
DataModel.getInstance().addItem(data);
break;
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
}
}
public interface OnItemAddedHandler { // Srains code
public void onItemAdded(Object data);
}
}
这是HistoryFragment(请记住它是ViewPager
的一部分):
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.RiThBo.noter.QuickNoteFragment.OnItemAddedHandler;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class HistoryFragment extends FragmentBase implements OnItemAddedHandler {
ListView lv;
List<Map<String, String>> planetsList = new ArrayList<Map<String, String>>();
SimpleAdapter simpleAdpt;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.history, container, false);
initList();
ListView lv = (ListView) view.findViewById(R.id.listView);
simpleAdpt = new SimpleAdapter(getActivity(), planetsList,
android.R.layout.simple_list_item_1, new String[] { "planet" },
new int[] { android.R.id.text1 });
lv.setAdapter(simpleAdpt);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parentAdapter, View view,
int position, long id) {
// We know the View is a TextView so we can cast it
TextView clickedView = (TextView) view;
Toast.makeText(
getActivity(),
"Item with id [" + id + "] - Position [" + position
+ "] - Planet [" + clickedView.getText() + "]",
Toast.LENGTH_SHORT).show();
}
});
registerForContextMenu(lv);
return view;
}
private void initList() {
// We populate the planets
planetsList.add(createPlanet("planet", "Mercury"));
planetsList.add(createPlanet("planet", "Venus"));
planetsList.add(createPlanet("planet", "Mars"));
planetsList.add(createPlanet("planet", "Jupiter"));
planetsList.add(createPlanet("planet", "Saturn"));
planetsList.add(createPlanet("planet", "Uranus"));
planetsList.add(createPlanet("planet", "Neptune"));
}
private HashMap<String, String> createPlanet(String key, String name) {
HashMap<String, String> planet = new HashMap<String, String>();
planet.put(key, name);
return planet;
}
// We want to create a context Menu when the user long click on an item
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
HashMap map = (HashMap) simpleAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options for " + map.get("planet"));
menu.add(1, 1, 1, "Details");
menu.add(1, 2, 2, "Delete");
}
@Override
public void onItemAdded(Object data) {
// to add item
String string = String.valueOf(data);
Toast.makeText(getContext(), "Data: " + string, Toast.LENGTH_SHORT).show();
planetsList.add(createPlanet("planet", string));
}
@Override
public void onStart() {
super.onStart();
DataModel.getInstance().setOnItemAddedHandler(this);
}
}
这是FragmentBase:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
public class FragmentBase extends Fragment {
private FragmentActivity mActivity; // I changed it to FragmentActivity because Activity was not working, and my `NavDrawer` is a FragmentActivity.
public void setContext(FragmentActivity activity) {
mActivity = mActivity;
}
public FragmentActivity getContext() {
return mActivity;
}
}
这是DataModel:
import android.util.Log;
import com.xxx.xxx.QuickNoteFragment.OnItemAddedHandler;
public class DataModel {
private static DataModel instance;
private static OnItemAddedHandler mOnItemAddHandler;
public static DataModel getInstance() {
if (null == instance) {
instance = new DataModel();
}
return instance;
}
public void setOnItemAddedHandler(OnItemAddedHandler handler) {
mOnItemAddHandler = handler;
}
public void addItem(Object data) {
if (null != mOnItemAddHandler)
mOnItemAddHandler.onItemAdded(data);
else {
Log.i("is context null?", "yes!");
}
}
}
谢谢
答案 0 :(得分:1)
我建议您使用interface
和MVC
,这将使您的代码更易于维护。
首先你需要一个界面:
public interface OnItemAddedHandler {
public void onItemAdded(Object data);
}
然后,您将需要一个数据模型:
public class DataModel {
private static DataModel instance;
private static OnItemAddedHandler mOnItemAddHandler;
public static DataModel getInstance() {
if (null == instance) {
instance = new DataModel();
}
return instance;
}
public void setOnItemAddedHandler(OnItemAddedHandler handler) {
mOnItemAddHandler = handler;
}
public void addItem(Object data) {
if (null != mOnItemAddHandler)
mOnItemAddHandler.onItemAdded(data);
}
}
单击该按钮时,可以将数据添加到数据模型中:
Object data = null;
DataModel.getInstance().addItem(data);
然后,FragmentB
实现了接口OnItemAddedHandler
以添加项
public class FragmentB implements OnItemAddedHandler {
@Override
public void onItemAdded(Object data) {
// to add item
}
}
此外,当FragmentB
开始时,您应该将自己注册到DataModel:
public class FragmentB implements OnItemAddedHandler {
@Override
public void onItemAdded(Object data) {
// to add item
}
@Override
protected void onStart() {
super.onStart();
DataModel.getInstance().setOnItemAddedHandler(this);
}
}
您还可以将DataModel.getInstance().setOnItemAddedHandler(this);
添加到onCreate
的{{1}}方法
FragmentB
<强>更新强>
你可以简单地发送字符串:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DataModel.getInstance().setOnItemAddedHandler(this);
// do other things
}
然后在 String data = "some string";
DataModel.getInstance().addItem(data);
FragementB
<强>更新强>
行。您已在 public class FragmentB implements OnItemAddedHandler {
@Override
public void onItemAdded(Object data) {
// get what you send into method DataModel.getInstance().addItem(data);
String string = String.valueOf(data);
}
}
方法中添加DataModel.getInstance().setOnItemAddedHandler(this)
,因此无需在onCreateView
方法中添加onStart()
方法。您可以删除整个onStart
方法。
onStart
,我们无需在onCreateView
中调用它。调用方法onItemAdded
时会调用DataModel.getInstance().addItem(data)
,我们也不需要在onCreateView
中调用它。
因此,您可以从onCreateView
方法中删除以下代码:
DataModel.getInstance().setOnItemAddedHandler(this);
// remove the methods below
// onItemAdded(getView());
// onStart();
你有另一个片段,其中有一个按钮,你可以在clickhandler函数中添加以下代码:
String data = "some string";
DataModel.getInstance().addItem(data);
<强> UPDATE3 强>
我认为HistoryFragment
已经分离到QuickNoteFragment
之后
您可以将代码添加到HistoryFragment
以检查:
@Override
public void onDetach() {
super.onDetach();
Log.i("test", String.format("onDetach! %s", getActivity() == null));
}
<强> UPDATE4 强>
我认为HistoryFragment
和QuickNoteFragment
应该有一个名为FragmentBase
的父类:
public class FragmentBase extends Fragment {
private Activity mActivity;
public void setContext(Activity activity) {
mActivity = mActivity;
}
public Activity getContext() {
return mActivity;
}
}
HistoryFragment
和QuickNoteFragment
延伸FragmentBase
。然后,当您在它们之间切换时,可以调用setContext
来设置活动,例如:
private void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (position == 0) {
Fragment qnfragment = new QuickNoteFragment();
qnfragment.setContext(this);
// ...
} else if (position == 1) {
Fragment pagerFragment = new RemViewPager();
pagerFragment.setContext(this);
// ...
}
}
现在,我们可以通过调用HistoryFragment
在getContext
中获取非空活动,因此我们可以将onItemAdded
方法更改为:
@Override
public void onItemAdded(Object data) {
// to add item
String string = String.valueOf(data);
Toast.makeText(getContext(), "Data: " + string, Toast.LENGTH_SHORT).show();
planetsList.add(createPlanet("planet", string));
}
我希望这会奏效。
答案 1 :(得分:1)
一些优秀的设计原则:
基于这些原则的建议方法(非正式设计模式)。
每个片段都应该声明一个由其父活动实现的接口:
public class MyFragment extends Fragment
{
public interface Parent
{
void onMyFragmentSomeAction();
}
private Parent mParent;
public onAttach(Activity activity)
{
mParent = (Parent) activity;
}
// This would actually be in a listener. Simplifying to save typing.
void onSomeButtonClick(View button)
{
mParent.onMyFragmentSomeAction();
}
}
活动应该为所有包含的片段实现适当的接口。
public class MyActivity extends Activity
implements MyFragment.Parent,
YourFragment.Parent,
HisFragment.Parent
{
[usual Activity code]
void onMyFragmentSomeAction()
{
if yourFragment is showing
{
yourFragment.reactToSomeAction();
}
if hisFragment is showing
{
hisFragment.observeThatSomeActionHappened();
}
[etc]
}
广播方法也很好,但它非常重量级,它需要目标片段才能知道源片段将发送什么广播。
答案 2 :(得分:0)
public void addListItem()
,它将数据添加到B中的listview。片段A尝试使用FragmentMananger.findFragmentByTag()
查找片段B的实例并调用此方法。< / LI>
醇>