Java 如何从片段在活动中设置公共文本视图?

Java 如何从片段在活动中设置公共文本视图?,java,android,android-fragments,android-activity,Java,Android,Android Fragments,Android Activity,我想从片段设置活动中textview的文本。我就是这样做的 MainActivity.java public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { public TextView textViewNotification; @Override protected void onCreate(Bund

我想从片段设置活动中textview的文本。我就是这样做的

MainActivity.java

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    public TextView textViewNotification;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        textViewNotification = (TextView) MenuItemCompat.getActionView(navigationView.getMenu().findItem(R.id.nav_notification));
    }
}
public class HomeFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        ((MainActivity)getActivity()).getSupportActionBar().setTitle("PIT IAI & FIP Regional");

        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_home, container, false);

        MainActivity activity = (MainActivity) getActivity();
        activity.notification.setText("This is a test"); // => got error here.

        return root;
    }
}
HomeFragment.java

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    public TextView textViewNotification;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        textViewNotification = (TextView) MenuItemCompat.getActionView(navigationView.getMenu().findItem(R.id.nav_notification));
    }
}
public class HomeFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        ((MainActivity)getActivity()).getSupportActionBar().setTitle("PIT IAI & FIP Regional");

        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_home, container, false);

        MainActivity activity = (MainActivity) getActivity();
        activity.notification.setText("This is a test"); // => got error here.

        return root;
    }
}
但它不起作用。这是我得到的错误:

android.content.res.Resources$NotFoundException: String resource ID #0x1
    at android.content.res.Resources.getText(Resources.java:348)
    at android.widget.TextView.setText(TextView.java:5846)

如何从片段中获取和设置活动的公共属性?不可能吗?请提供帮助。

Henry Gunawan您的主要活动没有任何名为notification的公共字段,您实际上将其命名为textViewNotification

此外,我在您的代码中看到了一些不好的做法

  • 避免声明公共字段,而是使用getter和setter来访问它们

  • 您的片段假设它的主机始终是MainActivity实例,并且它有一个名为notification的字段,这不是一个好的做法,片段应该是一个独立的单元,片段不应该取决于其主机活动的具体情况,因为它们可能是任何活动的主机,因此这是对片段的滥用,如果您希望您的主机活动为您做一些事情(如Amr Sakr所述),则应该使用回调


  • 假设您希望基于某个操作将文本发送到活动

    您可以使用一个接口,首先在片段中创建一个公共接口,并在其中添加一个方法,该方法接受一个字符串参数

    public interface CommunicateWithActivity{
       void onCommunicate(String s)
     }
    
    ,声明CommunicateWithActivity类型的全局变量mListener

    private CommunicateWithActivity mListener;
    
    然后覆盖转速表和内部尝试/捕捉块

    @Override
        public void onAttach(@NonNull Context context) {
            super.onAttach(context);
            try {
                mListener = (CommunicateWithActivity) context;
            } catch (ClassCastException e) {
                throw new ClassCastException(context.toString() + "CommunicateWithActivity implementation in Activity is required");
            }
    
        } 
    
    然后在活动中实现接口,在活动中重写“oncommunicate(String s)”方法,您将在方法中获得字符串

    @Override
        public void onCommunicate(String s) {
          //do whatever you want
        }
    

    将“thisatest”移动到stringresources并用R.string替换它。testIt最好从构造函数获取它。这样,用户就可以在同一个活动中使用片段的多个实例。这种情况很少见,但易于阅读和实现。