在Android中,在选项卡内启动活动

33

这是问题的情况:我有一个带有三个选项卡的应用程序。通过与选项卡中的项目进行各种交互,我最终会启动其他活动。客户已经审查了这一点,并希望在选项卡“内部”启动活动,以便选项卡保持可见性,如果用户单击选项卡,则返回到setContent函数中定义的原始活动。这是否可能?如何从其他活动(即子活动,而不是定义TabHost并具有调用setContent访问权限的活动)实现这一点?

7个回答

44

可以在选项卡中启动Activity,因此将tabspec内容设置为ActivityGroup而不是普通的Activity。

tabHost.addTab(tabHost.newTabSpec("Tab")
                .setIndicator("Tab")
                .setContent(new Intent(this, YourActivityGROUP.class)
                 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));

你可以在ActivityGroup中启动另一个Activity,像这样只更新当前选项卡的内容视图。

class YourActivityGROUP extends ActivityGroup{

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

      //you van get the local activitymanager to start the new activity

      View view = getLocalActivityManager()
                                .startActivity("ReferenceName", new
      Intent(this,YourActivity.class)
                                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
                                .getDecorView();
       this.setContentView(view);

   }
}

1
谢谢这个建议...实际上我认为这应该是未来实现此类功能的正确方式,因为它提供了更好的代码可维护性。 - samiq
嗨,谢谢。我可以在同一选项卡中调用新活动,但当返回到先前的活动时会出现问题。我正在从 ActivityGroup A 中调用 Activity B,现在我想再次移动到 ActivityGroup A。你能给我一个提示吗?谢谢。 - manidhar mulaparthi
它正在运行,但是在5个活动之后,它会意外地结束,因为栈已满。 - Chatar Veer Suthar
完美的解决方案。我的问题是它正在使用相同的意图启动多个活动,而在按下返回键时逐个终止...感谢您的帖子。 - Dinesh Prajapati
请帮我,我有不同模块的选项卡,在其中一个选项卡中表示设置,我想在设置选项卡中打开一个新的活动。我可以通过将设置选项卡活动作为ActivityGroup来实现这一点,但是当我按下子活动时,它会关闭应用程序,我想返回到设置活动。 - Shikhar
显示剩余2条评论

11

这是我的解决方案

public class ActivityStack extends ActivityGroup {

  private Stack<String> stack;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (stack == null) stack = new Stack<String>();
    //start default activity
    push("FirstStackActivity", new Intent(this, FirstStackActivity.class));
  }

  @Override
  public void finishFromChild(Activity child) {
    pop();
  }

  @Override
  public void onBackPressed() {
    pop();
  }


  public void push(String id, Intent intent) {
    Window window = getLocalActivityManager().startActivity(id, intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
    if (window != null) {
      stack.push(id);
      setContentView(window.getDecorView());
    }
  }

  public void pop() {
    if (stack.size() == 1) finish();
    LocalActivityManager manager = getLocalActivityManager();
    manager.destroyActivity(stack.pop(), true);
    if (stack.size() > 0) {
      Intent lastIntent = manager.getActivity(stack.peek()).getIntent();
      Window newWindow = manager.startActivity(stack.peek(), lastIntent);
      setContentView(newWindow.getDecorView());
    }
  }
}

启动选项卡

Intent intent = new Intent().setClass(this, ActivityStack.class);
TabHost.TabSpec spec = tabHost.newTabSpec("tabId")
spec.setContent(intent);

调用下一个活动

public class FirstStackActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TextView textView = new TextView(this);
    textView.setText("First Stack Activity ");
    textView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
          Intent intent = new Intent();
          intent.setClass(getParent(), SecondStackActivity .class);
          ActivityStack activityStack = (ActivityStack) getParent();
          activityStack.push("SecondStackActivity", intent);


      }
    });
    setContentView(textView);
  }
}

再次调用 next

public class SecondStackActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TextView textView = new TextView(this);
    textView.setText("First Stack Activity ");
    textView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
          Intent intent = new Intent();
          intent.setClass(getParent(), ThirdStackActivity .class);
          ActivityStack activityStack = (ActivityStack) getParent();
          activityStack.push("ThirdStackActivity", intent);


      }
    });
    setContentView(textView);
  }
}

适用于模拟器 2.2


实际上,有一个相当大的 bug - 如果你从活动 A 开始一个活动 B 然后在活动 A 中使用 finish(),上面的代码实际上会结束活动 B。 - Artem Russakovskii

3

1

你可以使用

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

对于每个你设置为tabSpec内容的活动,它将在你点击选项卡时创建此活动。

0

我该如何从工具栏的下拉菜单中打开一个片段或活动?

import android.content.Intent; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log; import android.view.Menu;
import android.view.MenuItem; import android.view.View;
import android.widget.AdapterView; import android.widget.ArrayAdapter;
import android.widget.Spinner;


> public class MainActivity extends AppCompatActivity {
> 
>     @Override
>     protected void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>         setContentView(R.layout.activity_main);
> 
>         //Appbar
>         Toolbar toolbar = (Toolbar) findViewById(R.id.appbar);
>         setSupportActionBar(toolbar);
>         getSupportActionBar().setDisplayShowTitleEnabled(false);
> 
>         //Appbar page filter
>         Spinner cmbToolbar = (Spinner) findViewById(R.id.CmbToolbar);
> 
>         ArrayAdapter<String> adapter = new ArrayAdapter<>(
>                 getSupportActionBar().getThemedContext(),
>                 R.layout.appbar_filter_title,
>                 new String[]{"Opción 1 ", "Opción 2 ", "Opción 3 "});
> 
>         adapter.setDropDownViewResource(R.layout.appbar_filter_list);
> 
>         cmbToolbar.setAdapter(adapter);
> 
>         cmbToolbar.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
>             @Override
>             public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
>                 //... Acciones al seleccionar una opción de la lista
>                 Log.i("Toolbar 3", "Seleccionada opción " + position);
> 
>                 Fragment f = null;
> 
>                 switch(position) {
>                     case 0:
>                         f = Fragment2.newInstance();
>                         break;
> 
>                     case 1:
>                         f = Fragment1.newInstance();
>                         break;
> 
>                 }
>             }
> 
>             @Override
>             public void onNothingSelected(AdapterView<?> adapterView) {
>                 //... Acciones al no existir ningún elemento seleccionado
>             }
>         });
>     }
> 
>     @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_main, menu);
>         return true;
>     }
> 
>     @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 position = item.getItemId();
> 
>         Fragment f = null;
> 
>         switch(position) {
>             case 0:
>                 f = Fragment2.newInstance();
>                 break;
> 
>             case 1:
>                 f = Fragment1.newInstance();
>                 break;
> 
>             case 2:
>                 Intent intent = new Intent(getApplicationContext(), Fragment1.class);
>                 startActivity(intent);
>                 break;
> 
>         }
>         return super.onOptionsItemSelected(item);
>     }
> 
> 
>     public Fragment getItem(int position) {
> 
>         Fragment f = null;
> 
>         switch(position) {
>             case 0:
>                 f = Fragment2.newInstance();
>                 break;
> 
>             case 1:
>                 f = Fragment1.newInstance();
>                 break;
> 
>             case 2:
>                 Intent intent = new Intent(getApplicationContext(), Fragment1.class);
>                 startActivity(intent);
>                 break;
> 
>         }
> 
>         return f;
>     } }

0

commonsware.com 是正确的,这是不可能的。我遇到了类似的问题,但只有一个活动被启动。我牺牲了一些架构并删除了从选项卡内部启动的活动。我将代码放在一个视图中,然后将 ViewAnimator 添加到选项卡的活动中。我覆盖了返回按钮,并删除了该视图(如果已经存在),否则让返回按钮正常工作。

这样做可以欺骗得足够好,而且对于仅涉及一个相关活动的情况,我不会因设计考虑而失眠。


0
这个问题中有两个选项卡,第一个是底部菜单选项卡,第二个是顶部选项卡,它们分别对应不同的活动和XML文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接