【问题标题】:Set Text of EditeText of Fragment from Activity在Activity的Fragment中设置EditText的文本
【发布时间】:2020-06-23 02:09:32
【问题描述】:

如何从 Activity 中设置 Fragment 的 EditText 的文本?

这里是活动代码:

public class MainActivity extends AppCompatActivity 
{
    FrameLayout simpleFrameLayout;
    TabLayout tabLayout;
    EditText editText;
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        simpleFrameLayout = (FrameLayout) findViewById(R.id.simpleFrameLayout);
        tabLayout = (TabLayout) findViewById(R.id.simpleTabLayout);
// Create a new Tab named "First"
        TabLayout.Tab firstTab = tabLayout.newTab();
        firstTab.setText("Personal"); // set the Text for the first Tab
        tabLayout.addTab(firstTab); // add  the tab at in the TabLayout
// Create a new Tab named "Second"
        TabLayout.Tab secondTab = tabLayout.newTab();
        secondTab.setText("Chat"); // set the Text for the second Tab
        tabLayout.addTab(secondTab); // add  the tab  in the TabLayout
        
        
        
        try {
            Fragment fragment = null;
            fragment = new FirstFragment();
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.replace(R.id.simpleFrameLayout, fragment);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            ft.commit();
        }
        catch (Exception e) {

        }
        
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
// get the current selected tab's position and replace the fragment accordingly
                    try {
                        Fragment fragment = null;
                    switch (tab.getPosition()) {
                        case 0:
                            fragment = new FirstFragment();
                            break;
                        case 1:
                            fragment = new SecondFragment();
                            break;
                    }
                        FragmentManager fm = getSupportFragmentManager();
                        FragmentTransaction ft = fm.beginTransaction();
                    ft.replace(R.id.simpleFrameLayout, fragment);
                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                        ft.commit();
                    }
                    catch (Exception e) {
                        
                    }
                }

                @Override
                public void onTabUnselected(TabLayout.Tab tab) {

                }

                @Override
                public void onTabReselected(TabLayout.Tab tab) {

                }
            });
        
    }
    
    public void connect(){
        //set text of EditText of SecondFragment
    }
}

我正在寻找解决此问题的方法: 我想创建一个聊天客户端,为此我需要不时更新选项卡的 EditText 而无需切换到该选项卡。我还需要在切换标签时不丢失该 EditText 的内容。

【问题讨论】:

  • 如果你不想丢失输入,那为什么要替换片段而不保留前一个呢?技术上添加的片段会保留它们的状态,每次切换标签时您只是将它们删除。
  • 我不知道如何保留旧的:(
  • 您需要在if(savedInstanceState == null) { 时添加两个片段,但在未显示时保留其中一个fragmentTransaction.detach()ed。从技术上讲,这也是FragmentPagerAdapterViewPager 中的工作方式。您可以使用fragmentManager.findFragmentByTag() 找到现有的 Fragment 实例。
  • 如果您不断收到“静态 EditText”(这是一种反模式)的答案,我可能需要编写一个完整的解决方案...
  • 我怎样才能通过切换标签来保留其中一个 fragmentTransaction.detach()?

标签: java android android-fragmentactivity android-tablayout


【解决方案1】:

只需在主要活动中创建一个变量,您就可以从片段中更新它。由于活动的生命周期不会从一个片段更改为另一个片段,因此您可以从第二个片段中获取相同的值。

我希望这会有所帮助。

【讨论】:

  • 但是在切换标签页的时候呢?一个标签的内容会丢失...
【解决方案2】:

假设您不想使用 ViewPagerPagerAdapter(您不需要在标签之间滑动),它应该是这样的:

public class MainActivity extends AppCompatActivity 
{
    FrameLayout simpleFrameLayout;
    TabLayout tabLayout;
    EditText editText;

    FirstFragment firstFragment;
    SecondFragment secondFragment;

    private int selectedTabIndex = 0;
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        simpleFrameLayout = findViewById(R.id.simpleFrameLayout);
        tabLayout = findViewById(R.id.simpleTabLayout);

        TabLayout.Tab firstTab = tabLayout.newTab();
        firstTab.setText("Personal");
        tabLayout.addTab(firstTab);

        TabLayout.Tab secondTab = tabLayout.newTab();
        secondTab.setText("Chat");
        tabLayout.addTab(secondTab);

        FragmentManager fm = getSupportFragmentManager();

        if (savedInstanceState == null) {
            firstFragment = new FirstFragment();
            secondFragment = new SecondFragment();

            fm.beginTransaction()
              .add(R.id.simpleFrameLayout, firstFragment, "firstFragment")
              .add(R.id.simpleFrameLayout, secondFragment, "secondFragment");
              .detach(secondFragment)
              .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
              .commitNow();
        } else {
            firstFragment = (FirstFragment) fm.findFragmentByTag("firstFragment");    
            secondFragment = (SecondFragment) fm.findFragmentByTag("secondFragment");

            this.selectedTabIndex = savedInstanceState.getInt("selectedTabIndex", 0);
            // selectTab(selectedTabIndex); // you don't need this line
        }
        
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    this.selectedTabIndex = tab.getPosition();
                    selectTab(selectedTabIndex);
                }

                @Override
                public void onTabUnselected(TabLayout.Tab tab) {

                }

                @Override
                public void onTabReselected(TabLayout.Tab tab) {

                }
            });
    }

    private void selectTab(int selectedTabIndex) {
        FragmentManager fm = getSupportFragmentManager();

        if (selectedTabIndex == 0) {
            fm.beginTransaction()
              .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
              .detach(secondFragment)
              .attach(firstFragment)
              .commitAllowingStateLoss();
        } else if(selectedTabIndex == 1) {
            fm.beginTransaction()
              .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
              .detach(firstFragment)
              .attach(secondFragment)
              .commitAllowingStateLoss();
        }
    }
    
    public void connect(){
        secondFragment.updateText("someText"); // this can run when secondFragment has no view!
    }
}

注意:如果您需要使用更多选项卡,那么您可以使用数组,但您仍然需要初始化/重新初始化,如本 sn-p 所示。

【讨论】:

  • 感谢您的合作。使用您的代码,我在运行应用程序之前会遇到一些错误。正因为如此,我稍微改变了它。我告诉你它在哪里出错以及代码出错时的样子:pastebin.com/6Gu36V6i。然后我向您展示当我尝试在 onCreateView 方法之外访问 Fragments View 时应用程序运行无错误后得到的异常:pastebin.com/YtHyF5Bn
  • 嗯。这是一个早于 compileSdkVersion 26 的项目?有趣的。只有当视图未分离时,视图才会存在,您需要检查视图是否可用,并在字段中设置值。如果视图不可用,那么它将在 onCreateView 中并且应该从字段中初始化(如果视图可用,则设置它 - getView() 是东西)
  • 我在代码中所做的更改是正确还是错误?当视图不可用时,应该从哪个字段初始化视图?在 onCreateView 方法中?
  • 在 Fragment 中创建一个字符串字段。更新后,检查视图是否可用。如果是,请同时更新 EditText。将字段的值设置为 onCreateView 中的 EditText。将String值持久化到onSaveInstanceState,并在savedInstanceState != null时在onCreate中恢复。是的,这确实是片段的工作方式,哈哈。
  • 但是当我恢复一个字符串值时,它可以包含数千个单词......如果你必须在标签中加载这么多,应用程序会变得越来越慢,对吧?跨度>
【解决方案3】:

基于您的一般问题的一般答案 使您的编辑文本公开静态public static EditText editText; 为它分配一个值,然后像MainActivity.editText.setText(""); 一样从任何其他类调用它 ` 仅在绝对必要时才使用此方法,因为它可能会导致内存泄漏,因为您必须在使用后手动销毁/取消对象

【讨论】:

  • 不,你根本不应该这样做。它是 Android 开发中的一种反模式。
  • 我同意。如果静态视图管理不善/未销毁,则内存泄漏只是编辑以明确说明这只是一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多