【问题标题】:Android Getting Fragment ID for use in Switch statementAndroid 获取片段 ID 以在 Switch 语句中使用
【发布时间】:2015-05-26 16:19:21
【问题描述】:

所以,我正在编写应用程序的导航部分,并在 Activity 中动态创建片段。

我希望,当用户点击下一个或上一个箭头时,应用程序可以找出 Activity 中的片段,并将其替换为下一个或上一个片段。为此,我创建了一个 switch 语句来检查正在显示的片段。

我认为我可以通过使用来做到这一点

getSupportFragmentManager().findFragmentById(R.id.activity_public_internet)

但这似乎在 switch 语句中不起作用。

然后我尝试了

getFragmentManager().findFragmentById(R.id.public_internet_intro_fragment).getId()

这也不行。

这是完整的代码。任何帮助将不胜感激。如果有更好的方法,请随时告诉我。

public void goPrev(View view) {
        switch(getSupportFragmentManager().findFragmentById(R.id.activity_public_internet).getId()) {
            case R.id.public_internet_intro_fragment:
                Intent intent = new Intent(this, LearnActivity.class);
                startActivity(intent);
                break;
            case R.id.public_internet_topic_fragment:
                Fragment introFragment = new PublicInternetIntroFragment();
                FragmentTransaction exampleTransaction = getFragmentManager().beginTransaction();
                exampleTransaction.replace(R.id.activity_public_internet, introFragment);
                exampleTransaction.addToBackStack(null);
                exampleTransaction.commit();
                break;
            case R.id.public_internet_example_fragment:
                Fragment topicFragment = new PublicInternetTopicFragment();
                FragmentTransaction topicTransaction = getFragmentManager().beginTransaction();
                topicTransaction.replace(R.id.activity_public_internet, topicFragment);
                topicTransaction.addToBackStack(null);
                topicTransaction.commit();
                break;
        }
    }

    public void goNext(View view) {
        switch(getFragmentManager().findFragmentById(R.id.public_internet_intro_fragment).getId()) {
            case R.id.public_internet_intro_fragment:
                Fragment topicFragment = new PublicInternetTopicFragment();
                FragmentTransaction topicTransaction = getFragmentManager().beginTransaction();
                topicTransaction.replace(R.id.activity_public_internet, topicFragment);
                topicTransaction.addToBackStack(null);
                topicTransaction.commit();
                break;
            case R.id.public_internet_topic_fragment:
                Fragment exampleFragment = new PublicInternetExampleFragment();
                FragmentTransaction exampleTransaction = getFragmentManager().beginTransaction();
                exampleTransaction.replace(R.id.activity_public_internet, exampleFragment);
                exampleTransaction.addToBackStack(null);
                exampleTransaction.commit();
                break;
            case R.id.public_internet_example_fragment:
                Intent intent = new Intent(this, LearnActivity.class);
                startActivity(intent);
                break;
        }
    }

检查错误日志时,尝试调用int android.app.Fragment.getId()后引发空指针异常

编辑:添加 PublicInternetActivity.java

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;

public class PublicInternetActivity extends ActionBarActivity{
    private static final String tag_public_internet_intro_fragment = "public_internet_intro_fragment";
    private static final String tag_public_internet_topic_fragment = "public_internet_topic_fragment";
    private static final String tag_public_internet_example_fragment = "public_internet_example_fragment";

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

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_public_internet);

        introFrag();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu items for use in the action bar
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_learn, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_home) {
            goHome();
            return true;
        }
        else {
            return super.onOptionsItemSelected(item);
        }
    }

    public void introFrag() {
        Fragment introFragment = new PublicInternetIntroFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.activity_public_internet, introFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }

    public void goHome() {
        Intent homeIntent = NavUtils.getParentActivityIntent(this);
        NavUtils.navigateUpTo(this, homeIntent);
    }

    public void pushNewFragment( Fragment newFrag, String tag) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        transaction.replace(R.id.activity_public_internet, newFrag, tag);
        transaction.addToBackStack(tag);
        transaction.commit();
    }

    public String getActiveFragmentTag() {
        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
           return null;
        }
        String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
        return tag;
    }

    public void goPrev(View view) {
        switch(getActiveFragmentTag()) {
            case tag_public_internet_intro_fragment:
                Intent intent = new Intent(this, LearnActivity.class);
                startActivity(intent);
                break;
            case tag_public_internet_topic_fragment:
                Fragment introFragment = new PublicInternetIntroFragment();
                pushNewFragment(introFragment, tag_public_internet_intro_fragment);
                break;
            case tag_public_internet_example_fragment:
                Fragment topicFragment = new PublicInternetTopicFragment();
                pushNewFragment(topicFragment, tag_public_internet_topic_fragment);
                break;
        }
    }

    public void goNext(View view) {
        switch(getActiveFragmentTag()) {
            case tag_public_internet_intro_fragment:
                Fragment topicFragment = new PublicInternetTopicFragment();
                pushNewFragment(topicFragment, tag_public_internet_topic_fragment);
                break;
            case tag_public_internet_topic_fragment:
                Fragment exampleFragment = new PublicInternetExampleFragment();
                pushNewFragment(exampleFragment, tag_public_internet_example_fragment);
                break;
            case tag_public_internet_example_fragment:
                Intent intent = new Intent(this, LearnActivity.class);
                startActivity(intent);
                break;
        }
    }
}

【问题讨论】:

  • 简单的方法是使用带有标签的片段或检查这些答案:stackoverflow.com/q/6750069/1168654
  • 查看错误日志,是Null Pointer Exception,告诉我方法运行时页面中没有片段。

标签: android android-fragments switch-statement


【解决方案1】:

尝试这样做:

public void pushNewFragment( Fragment newFrag, String tag) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    transaction.replace(R.id.activity_public_internet, newFrag, tag);
    transaction.addToBackStack(tag);
    transaction.commit();
}

public String getActiveFragmentTag() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
       return null;
    }
    String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return tag;
}

public void goPrev(View view) {
    switch(getActiveFragmentTag()) {
        case tag_public_internet_intro_fragment:
            Intent intent = new Intent(this, LearnActivity.class);
            startActivity(intent);
            break;
        case tag_public_internet_topic_fragment:
            Fragment introFragment = new PublicInternetIntroFragment();
            pushNewFragment(introFragment, tag_public_internet_intro_fragment);
            break;
        case tag_public_internet_example_fragment:
            Fragment topicFragment = new PublicInternetTopicFragment();
            pushNewFragment(introFragment, tag_public_internet_topic_fragment);
            break;
    }
}

编辑

来自documentation

获取活动中存在的片段,用 findFragmentById() (for 在活动布局中提供 UI 的片段)或 findFragmentByTag()(用于提供或不提供 UI 的片段)。

通常我们对静态片段使用 id(嵌入在活动布局中,您不需要在运行时更改)。对于动态片段,这是您的情况,最好使用标签。

祝你好运

【讨论】:

  • 如果你不想在 String 上使用 switch(在 JAVA 1.7 中引入)你可以通过 if 语句来改变 switch
  • 非常感谢。所以,请随时告诉我这是否是完全错误的做法。我将这些片段放在自己单独的片段 xml 文件中,所以这样做是不对的?
  • 更新答案解释使用ids和tags的区别
  • 在这种情况下,tag_public_internet_intro_fragment 等需要是一组我需要设置的变量?
  • 没错,我认为最好的方法是在每个片段中定义一个最终的静态标签。例如,您可以将 tag_public_internet_intro_fragment 替换为 PublicInternetIntroFragment.TAG
【解决方案2】:

这看起来很复杂,我建议一些更简单的东西。

使用Fragment.instantiate 创建一个片段并替换当前片段。如果您的 Fragment 的顺序是固定的,请保留一个数组,其中包含每个 Fragment 的类的名称(按正确的顺序)。

然后,保留一个指针以了解您在 Array 中的位置,并且每次您转到下一个/上一个 Fragment 时,相应地增加您的指针。

这样,您不必逐案处理,这似乎很容易出错。您应该考虑以下情况

pointer == 0 and pointer == length-1.

这样,您可以一个接一个地拥有任意数量的片段。但是请注意,它仅适用于确定的订单。如果你想要更复杂的东西,你应该扩展 Fragment 类并将逻辑添加到你的子类中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多