所以目前我有一个可以从两个不同活动中获得的活动,问题是我只能将一个活动设置为清单XML文件中的父活动。显然这是糟糕的UX / UI设计,因为活动可能会将用户发回到之前的错误活动,因此我正在尝试动态设置哪个活动是父活动。
麻烦的是我不太确定如何处理这个问题,无论是代码还是XML,所以任何指针都会受到赞赏。 :)
答案 0 :(得分:55)
对于未来的读者,这里是一个如何根据developer guides实际实施官方/适当解决方案的示例(滚动到以开头的段落“这适用于父活动可能是不同... 强>“的)。
请注意,此解决方案假设您使用Support Library来实现ActionBar
,并且至少可以在清单XML文件中设置'默认'父活动,以便在活动时使用正在退出处于不属于您的应用程序的“任务”中(请阅读链接的文档以进行说明)。
// Override BOTH getSupportParentActivityIntent() AND getParentActivityIntent() because
// if your device is running on API 11+ it will call the native
// getParentActivityIntent() method instead of the support version.
// The docs do **NOT** make this part clear and it is important!
@Override
public Intent getSupportParentActivityIntent() {
return getParentActivityIntentImpl();
}
@Override
public Intent getParentActivityIntent() {
return getParentActivityIntentImpl();
}
private Intent getParentActivityIntentImpl() {
Intent i = null;
// Here you need to do some logic to determine from which Activity you came.
// example: you could pass a variable through your Intent extras and check that.
if (parentIsActivityA) {
i = new Intent(this, ActivityA.class);
// set any flags or extras that you need.
// If you are reusing the previous Activity (i.e. bringing it to the top
// without re-creating a new instance) set these flags:
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// if you are re-using the parent Activity you may not need to set any extras
i.putExtra("someExtra", "whateverYouNeed");
} else {
i = new Intent(this, ActivityB.class);
// same comments as above
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra("someExtra", "whateverYouNeed");
}
return i;
}
注意:如果您没有在清单XML文件中设置默认的父Activity,那么您还需要实现onCreateSupportNavigateUpTaskStack(),因为系统将不知道如何为您的任务生成一个Backstack。我没有提供这个部分的任何例子。
finish()
类型解决方案的想法在我搜索此问题的解决方案时,我遇到了一些答案,主张覆盖onOptionsItemSelected()
并拦截android.R.id.home
按钮的策略,以便他们可以简单finish()
当前{ {1}}返回上一个屏幕。
在许多情况下,这将达到预期的行为,但我只想指出,这绝对是不与正确的UP导航相同。如果您通过其中一个父活动导航到子Activity,则是Activity
将返回到正确的上一个屏幕,但是如果您通过通知输入子Activity,该怎么办?在这种情况下finish()
按下UP按钮会使您回到主屏幕或您在查看通知之前查看的任何应用程序,而是应该将您发送到应用程序中的正确父活动
答案 1 :(得分:27)
就像这样,您可以动态导航到您的父活动:
getActionBar().setDisplayHomeAsUpEnabled(true);
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
注意:它会将您重定向到您来自的活动或片段,无论它是否是父母。单击操作栏上/主页按钮将完成当前活动。
答案 2 :(得分:8)
这里有两个概念'Up'和'Back'。 “回来”是显而易见的:在我来到这里之前带我去我所在的地方。通常你不需要关心'后退',因为系统会处理它很好。 “向上”并不那么明显 - 它类似于缩小 - 从元素到集合,从细节到更宽广的画面。
哪些适合您的使用案例?
根据下面的评论:向上按钮从Android清单中提取目的地,但它可以是customized programmatically。
答案 3 :(得分:4)
要了解如何正确使用向上导航,请参阅this Android Dev Guide.
请注意,上面的Android开发指南存在一个很大的缺陷,因为NavUtils函数对ICS(及更低版本)和JellyBean(及更高版本)的工作方式不同。 NavUtils中的这个缺陷得到了很好的解释here.
答案 4 :(得分:4)
要覆盖的方法是getParentActivityIntent。
这是我的代码并且完美无缺。
@Override
public Intent getParentActivityIntent() {
Intent parentIntent= getIntent();
String className = parentIntent.getStringExtra("ParentClassSource");
Intent newIntent=null;
try {
//you need to define the class with package name
newIntent = new Intent(OnMap.this, Class.forName(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return newIntent;
}
来自父活动;
Intent i = new Intent(DataDetailsItem.this, OnMap.class);
i.putExtra("ParentClassSource", "com.package.example.YourParentActivity");
startActivity(i);
答案 5 :(得分:4)
通常,如果“详细”类型的活动具有嵌套/相关内容,则必须提供“向上”导航。 “后退”导航由系统处理,因此您真的不必担心它。
现在为支持“向上”导航付出了额外的努力,有几种方法可以实现:
具有AndroidManifest中定义的父活动的活动。
Your Detail Activity
--------------------
protected void replaceFragment(Bundle fragmentArguments, boolean addToBackStack) {
DetailFragment fragment = new DetailFragment();
fragment.setArguments(fragmentArguments);
// get your fragment manager, native/support
FragmentTransaction tr = fragmentManager.beginTransaction();
tr.replace(containerResId, fragment);
if (addToBackStack) {
tr.addToBackStack(null);
}
tr.commit();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
如果只有一个父活动意味着(DetailActivity)总是从(MainActivity)启动,那么这种方法很有效。否则,如果(DetailActivity)从不同的地方启动,则此解决方案将无效。 更多信息:http://developer.android.com/training/implementing-navigation/ancestral.html
(更简单和推荐)具有Fragment和Fragment back-stack的活动:
object.geometry.computeBoundingBox();
var boundingBox = object.geometry.boundingBox;
position = new THREE.Vector3();
position.subVectors( boundingBox.max, boundingBox.min );
position.multiplyScalar( 0.5 );
position.add( boundingBox.min );
position.applyMatrix4( object.matrixWorld );
object.geometry.applyMatrix(
new THREE.Matrix4()
.makeTranslation(
-(position.x),
-(position.y),
-(position.z)
)
);
object.geometry.verticesNeedUpdate = true;
object.position.x = position.x;
object.position.y = position.y;
object.position.z = position.z;
在此解决方案中,如果用户按下“back”,则片段将从片段backstack中弹出,并且用户将被恢复到之前的片段,同时仍保持相同的活动。如果用户按下“向上”,则活动解除并且用户返回到先前的活动(作为父活动)。这里的关键是使用Fragment作为UI,活动作为片段的主机。
希望这有帮助。
答案 6 :(得分:0)
您可以覆盖“向上”按钮以使其类似于“后退”按钮,如下所示:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
答案 7 :(得分:0)
科特琳2020
我的活动从不同的活动启动,因此AndroidManifest仅适用于1个父活动。
您可以像这样返回上一个活动:
supportActionBar?.setDisplayHomeAsUpEnabled(true)
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item!!.itemId){
android.R.id.home -> {
finish()
return true
}
}
return super.onOptionsItemSelected(item)
}