这个问题主要是为了寻求关于处理我的应用程序的最佳方法的意见。 我有一个活动正在处理三个片段。 片段A有一个可单击元素(照片),片段B有4个可单击元素(按钮)。 单击照片后,另一个片段仅显示详细信息。 我正在使用ActionBarSherlock。
前进和后退按钮需要将照片分别更改为下一个或上一个姿势。 我可以将照片和按钮放在同一片段中,但想让它们分开,以防我想在平板电脑中重新排列它们。
我需要一些建议-我应该结合片段A和片段B吗? 如果没有,我将需要弄清楚如何为3个可点击项实现接口。
我考虑过使用Roboguice,但是我已经使用SherlockFragmentActivity进行了扩展,所以这是不可行的。 我看到了Otto的提法,但是我没有看到关于如何将其包含在项目中的优秀教程。 您认为最佳设计实践应该是什么?
我还需要帮助弄清楚如何在片段和活动之间进行通信。 我想在应用程序中保留一些“全局”数据,例如pose ID。 除了股票android开发人员的信息外,我还能看到一些示例代码吗? 那并不是全部有帮助。
顺便说一句,我已经将每个姿势的所有信息存储在SQLite数据库中。 那是容易的部分。
在活动和片段之间进行通信的最简单方法是使用接口。 这个想法基本上是在给定的片段A内定义一个接口,然后让活动实现该接口。
一旦实现了该接口,您就可以在其覆盖的方法中做任何您想做的事情。
接口的另一个重要部分是您必须从片段中调用abstract方法,并记住将其强制转换为活动。 如果处理不正确,它将捕获ClassCastException。
在Simple Developer Blog上有一个很好的教程,介绍了如何完全执行此类操作。
希望对您有帮助!
建议在片段之间进行通信的方法是使用由主Activity管理的callbacks \\ listener。
我认为此页面上的代码非常清楚: http : //developer.android.com/training/basics/fragments/communicating.html
您还可以引用IO 2012 Schedule应用程序,该应用程序被设计为事实上的参考应用程序。 可以在这里找到: http : //code.google.com/p/iosched/
另外,这是一个具有良好信息的SO问题: 如何在片段之间传递数据
它是通过Callback接口实现的:
首先,我们必须创建一个接口:
public interface UpdateFrag {
void updatefrag();
}
在活动中执行以下代码:
UpdateFrag updatfrag ;
public void updateApi(UpdateFrag listener) {
updatfrag = listener;
}
从必须在Activity中触发回调的事件中得出:
updatfrag.updatefrag();
在Fragment实现中,
CreateView
的接口执行以下代码:
((Home)getActivity()).updateApi(new UpdateFrag() {
@Override
public void updatefrag() {
.....your stuff......
}
});
我制作了一个注释库,可以为您进行转换。 看一下这个。 https://github.com/zeroarst/callbackfragment/
@CallbackFragment
public class MyFragment extends Fragment {
@Callback
interface FragmentCallback {
void onClickButton(MyFragment fragment);
}
private FragmentCallback mCallback;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt1
mCallback.onClickButton(this);
break;
case R.id.bt2
// Because we give mandatory = false so this might be null if not implemented by the host.
if (mCallbackNotForce != null)
mCallbackNotForce.onClickButton(this);
break;
}
}
}
然后,它生成您片段的子类。 并将其添加到FragmentManager。
public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM")
.commit();
}
Toast mToast;
@Override
public void onClickButton(MyFragment fragment) {
if (mToast != null)
mToast.cancel();
mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT);
mToast.show();
}
}
要在Activity
和Fragment
之间进行通信,有几种选择,但是经过大量阅读和大量经验,我发现可以通过以下方式恢复它:
Activity
要与子Fragment
进行通信=>只需在Fragment
类中编写公共方法,然后让Activity
调用它们即可 Fragment
希望与父代进行交流Activity
=>这需要更多的工作,正如官方的Android链接https://developer.android.com/training/basics/fragments/communication所建议的那样,定义一个好主意一个由Activity
实现的interface
,它将与任何要与Fragment
通信的Activity
建立一个契约。 例如,如果您具有FragmentA
,它想与包含它的任何activity
进行通信,则定义FragmentAInterface
,它将定义FragmentA
可以为决定使用它的activities
调用哪种方法。 Fragment
想与其他分Fragment
通信=>这是您遇到最“复杂”情况的情况。 因为你可能需要从FragmentA数据传递给FragmentB,反之亦然,这可能会导致我们定义2个接口, FragmentAInterface
将由执行FragmentB
和FragmentAInterface
将由执行FragmentA
。 那将使事情变得混乱。 想象一下,如果您还有更多的Fragment
,甚至父activity
想与他们进行交流。 好了,这种情况是为activity
及其fragment
s建立共享ViewModel
的绝佳时机。 更多信息, 请参见https://developer.android.com/topic/libraries/architecture/viewmodel 。 基本上,您需要定义一个SharedViewModel
类,该类具有要在activity
和fragments
之间共享的所有数据,这些fragments
将需要在它们之间进行数据通信。 在ViewModel
情况下,最后使事情变得非常简单,因为您不必添加额外的逻辑即可使事情变得肮脏且混乱。 另外,它还允许您从Controller
( activities
和fragments
)中分离数据的收集(通过调用SQLite数据库或API)。
我不确定我是否真的了解您要做什么,但是建议的在片段之间进行通信的方法是对Activity使用回调,而不是直接在片段之间进行回调。 看到这里http://developer.android.com/training/basics/fragments/communicating.html
您可以在片段中创建带有函数声明的声明公共接口,并在活动中实现该接口。 然后,您可以从片段中调用该函数。
我正在使用Intent将动作传达回主要活动。 主要活动是通过重写onNewIntent(Intent intent)来监听这些内容。 例如,主要活动将这些动作转换为相应的片段。
因此,您可以执行以下操作:
public class MainActivity extends Activity {
public static final String INTENT_ACTION_SHOW_FOO = "show_foo";
public static final String INTENT_ACTION_SHOW_BAR = "show_bar";
@Override
protected void onNewIntent(Intent intent) {
routeIntent(intent);
}
private void routeIntent(Intent intent) {
String action = intent.getAction();
if (action != null) {
switch (action) {
case INTENT_ACTION_SHOW_FOO:
// for example show the corresponding fragment
loadFragment(FooFragment);
break;
case INTENT_ACTION_SHOW_BAR:
loadFragment(BarFragment);
break;
}
}
}
然后在任何片段中显示foo片段:
Intent intent = new Intent(context, MainActivity.class);
intent.setAction(INTENT_ACTION_SHOW_FOO);
// Prevent activity to be re-instantiated if it is already running.
// Instead, the onNewEvent() is triggered
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
getContext().startActivity(intent);