【问题标题】:How to setText to or findViewById from another class?如何从另一个类 setText 或 findViewById?
【发布时间】:2016-01-23 20:34:26
【问题描述】:

我对编码完全陌生 并一直在尝试制作药物剂量计算器 该应用程序的想法是顶部有一个Seekbar供用户调整体重 使所有药物自动显示计算剂量。

我在使用一个 MainActivity 和一个 XML 文件进行第一次试用时成功尝试 (参考图片http://i.stack.imgur.com/KhbN4.jpg

但是,当我第二次尝试使用可滑动视图创建选项卡布局时,一旦我触摸 Seekbar,应用程序就会强制关闭。 (参考图片http://i.stack.imgur.com/72SYw.png

我一直在关注这个来自 androidhive 的教程。

计算和显示的代码应该在 MainActivity 类还是在 Fragment 类中完成? 我想我的主要问题是我不知道如何从另一个类 setText 或 findViewById 。任何帮助表示赞赏。

使用新信息编辑: 从我第二次尝试的 onProgressChanged 方法中删除这三行后,Seekbar 再次工作以显示滑块的当前值。但是一旦我放回这三行来更新 textView,一旦我触摸 Seekbar,它就会强制关闭
mincefaclordose.setText(String.valueOf(minCefaclorDose)+"mg Q8H"); maxcefaclordose.setText(String.valueOf(maxCefaclorDose)+"mg Q8H"); zithromaxdose.setText(String.valueOf(zithromaxDose)+"mg Q24H");

我可以根据要求提供更多信息。

修复 textView ID 后我的新 logcat

10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 致命异常: main 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 进程: com.example.android.b, PID: 9910 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: java.lang.NullPointerException: 尝试调用虚拟方法'void android.widget.TextView.setText(java.lang.CharSequence) ' 在空对象引用上 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 com.example.android.b.MainActivity$1.onProgressChanged(MainActivity.java:58) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.widget.SeekBar.onProgressRefresh(SeekBar.java:93) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.widget.ProgressBar.doRefreshProgress(ProgressBar.java:1303) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.widget.ProgressBar.refreshProgress(ProgressBar.java:1315) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.widget.ProgressBar.setProgress(ProgressBar.java:1361) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.widget.AbsSeekBar.trackTouchEvent(AbsSeekBar.java:666) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.widget.AbsSeekBar.onTouchEvent(AbsSeekBar.java:595) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.View.dispatchTouchEvent(View.java:9294) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.app.Activity.dispatchTouchEvent(Activity.java:2765) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.View.dispatchPointerEvent(View.java:9514) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4230) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4096) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5922) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5896) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5857) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6025) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: 在 android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime:在 android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(本机方法) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.InputEventRe

//my success code
public class MainActivity extends AppCompatActivity {
SeekBar seekBar;
TextView BW;
TextView maxcefaclordose;
TextView mincefaclordose;
TextView zithromaxdose;


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

    seekBar = (SeekBar) findViewById(R.id.seekbar);
    BW = (TextView) findViewById(R.id.textView);
    mincefaclordose = (TextView) findViewById(R.id.cefaclormin);
    maxcefaclordose = (TextView) findViewById(R.id.cefaclormax);
    zithromaxdose = (TextView) findViewById(R.id.zithromaxdose);
    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            double trueBW = (double)(progress)/10;
            long maxCefaclorDose = Math.round(trueBW*40/3);
            long minCefaclorDose = Math.round(trueBW*20/3);
            long zithromaxDose =  Math.round(trueBW*10);

            BW.setText(String.valueOf(trueBW));
            mincefaclordose.setText(String.valueOf(minCefaclorDose)+"mg  Q8H");
            maxcefaclordose.setText(String.valueOf(maxCefaclorDose)+"mg  Q8H");
            zithromaxdose.setText(String.valueOf(zithromaxDose)+"mg  Q24H");
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }

    });
};

}

//here start the code I fail on second trial

public class MainActivity extends AppCompatActivity {
SeekBar seekBar;
TextView BW;
TextView maxcefaclordose;
TextView mincefaclordose;
TextView zithromaxdose;

@Override
protected void onCreate(Bundle savedInstanceState) {
    Toolbar toolbar;
    TabLayout tabLayout;
    ViewPager viewPager;

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    seekBar = (SeekBar) findViewById(R.id.seekbar);
    BW = (TextView) findViewById(R.id.textView);
    mincefaclordose = (TextView) findViewById(R.id.cefaclormin);
    maxcefaclordose = (TextView) findViewById(R.id.cefaclormax);
    zithromaxdose = (TextView) findViewById(R.id.zithromaxdose);
    toolbar = (Toolbar) findViewById(R.id.toolbar);

    setSupportActionBar(toolbar);


    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            double trueBW = (double)(progress)/10;
            long maxCefaclorDose = Math.round(trueBW*40/3);
            long minCefaclorDose = Math.round(trueBW*20/3);
            long zithromaxDose =  Math.round(trueBW*10);

            BW.setText(String.valueOf(trueBW));
            mincefaclordose.setText(String.valueOf(minCefaclorDose)+"mg  Q8H");
            maxcefaclordose.setText(String.valueOf(maxCefaclorDose)+"mg  Q8H");
            zithromaxdose.setText(String.valueOf(zithromaxDose)+"mg  Q24H");

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    });
    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);
    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new URTI(), "URTI");
    adapter.addFragment(new AntimicrobialFragment(), "Anti-\nmicrobials");
    adapter.addFragment(new Others(), "Others");
    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}
}

// 我的activity_main.xml

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    <LinearLayout
        android:id="@+id/top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10sp"
        android:layout_marginBottom="10sp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView"
            android:paddingLeft="8sp"
            android:layout_width="40sp"
            android:layout_height="wrap_content"
            android:text="6.0" />

        <TextView
            android:id="@+id/kg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/textView"
            android:text="kg" />

        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/kg"
            android:max="500"
            android:progress="60" />
    </LinearLayout>
    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"
        app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

【问题讨论】:

  • 能否将 logcat 报告添加到问题中
  • 您的问题的标题中没有关于您的问题的信息
  • 对不起大家,我已经添加了logcat并更新了我的标题
  • @SimonHo 请检查更新的答案以将值从活动传递到片段

标签: android android-fragments android-activity


【解决方案1】:

您收到的 NPE(NullPointerException) bcoz 的 TextView id 不正确

获取你的成功代码部分

setContentView(R.layout.activity_main);

seekBar = (SeekBar) findViewById(R.id.seekbar);
BW = (TextView) findViewById(R.id.textView);

获取你的失败代码部分

setContentView(R.layout.activity_main);
seekBar = (SeekBar) findViewById(R.id.seekbar);
BW = (TextView) findViewById(R.id.BWtextView);

正如您在上面看到的,在这两种情况下,您都使用activiy_main 作为布局,但BW TextView 的ID 不同,因此解决方案是使用R.id.textView 而不是R.id.BWtextView。但如果你想要R.id.BWtextView,那么请确保在activity_main 布局中保持id 相同

建议:请从here 中准确了解什么是 NPE。和 你可以很容易地修复它,因为在 logcat 报告中你可以 显然是给出这个 NPE 并导致崩溃的行 应用程序。

根据以下 cmets 更新
不知道你有没有解决传值的问题...反正
解决方案一:在fragment中创建所需TextViews的全局变量并写一个方法例如...

public class MainActivityFragment extends Fragment {
  //your code
  TextView textView;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
  //your code
  textView = .....findViewById(R.id.texViewId)
  }

  //your code

  void setTextView(String text){
      textView.setText(text);
  }

然后在您的 Activity 中,而不是直接执行 adapter.addFragment(new AntimicrobialFragment(), "Anti-\nmicrobials"); 为片段创建一个全局变量,然后在 Listener 中您可以执行以下操作。

Fragment antimicrobialFragment;  
//your code 

antimicrobialFragment = new AntimicrobialFragment(); 
//your code 

//Inside setupViewPagerAdapter
adapter.addFragment(antimicrobialFragment, "Anti-\nmicrobials");

//Inside onProgressChanged in onSeekBarChangeListener
if(null != antimicrobialFragment && antimicrobialFragment .isVisible()){
   ((AntimicrobialFragment)antimicrobialFragment ).setTextView("Sample Text");
} else {
   //just to verify 
   Toast.makeText(getBaseContext(),"Fragment is notVisible",Toast.LENGTH_LONG).show();
}

解决方案 2 使用带有片段的自定义侦听器。

【讨论】:

  • 实际上我在第二次尝试中确实将 textview ID 更改为 BWtextView。现在我恢复到与第一次尝试相同的 ID,但我仍然强制关闭
  • 但这次错误可能已经改变,请使用新的 logcat 报告更新问题
  • 感谢您的帮助。我已将 ID 恢复为 textView 并发布了新的 logcat
  • 对我来说,您的新 logcat 报告和旧 logcat 报告看起来相同...但是从错误中我可以说 TextView id 与布局中存在的 TextView 不匹配,请正确检查。因为当你做 findViewById 如果布局中不存在那么它会返回 null 而当你做 null.setText 它抛出异常
  • 你可以在问题中发布activity_main
猜你喜欢
  • 2012-01-04
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
  • 2016-04-04
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
相关资源
最近更新 更多