所以这就是问题所在。我正在使用片段和按钮内的两个EditText视图编写应用程序。单击该按钮时,它会更改EditText的文本。在onViewCreated()方法中,我使用此代码获取EditText实例并将其存储到变量中。
EditText box1 = (EditText)(getView.findViewById(R.id.box1));
这很好用。但是,当我单击按钮时尝试访问变量box1时,EditText变为null并抛出NullPointerException。有谁知道为什么会这样?
这是片段代码:
public class MyFragment extends Fragment {
EditText box1, box2;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_text_coder_free,
container, false);
//Works here.
box1 = (EditText)(rootView.findViewById(R.id.box1));
box2 = (EditText)(rootView.findViewById(R.id.box2));
//Same thing. Sets the text correctly
box1.setText("hey look at me!");
return rootView;
}
//Called when the button is clicked.
public void setBox1Text(String text) {
//It's null here so it skips to the else
if(box1 != null) {
box1.setText(text);
}
else {
//This doesn't work. Throws the exception here.
box1 = (EditText)(getView().findViewById(R.id.box1));
}
}
public void setBox2Text(String text) {
if(box2 != null) {
box2.setText(text);
}
else {
//This doesn't work. Throws the exception here.
box2 = (EditText)(getView().findViewById(R.id.box2));
}
}
public String getBox1Text() {
if(box1 == null) {
return "Nice try.";
}
return box1.getText().toString();
}
public String getBox2Text() {
if(box2 == null) {
return "Nice try.";
}
return box2.getText().toString();
}
}
这是包含片段的活动:
public class MyActivity extends Activity {
MyFragment myFragment
EditText box1, box2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_coder);
if (savedInstanceState == null) {
myFragment = new MyFragment();
getFragmentManager().beginTransaction()
.add(R.id.container, myFragment.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my_app, 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 id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void box1Click(View v) {
myFragment.setBox2Text("Some text");
}
public void box2Click(View v) {
myFragment.setBox2Text("Some text");
}
}
以下是片段中的XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.mycode.MyFragment" >
<EditText
android:id="@+id/box1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:inputType="textMultiLine" />
<EditText
android:id="@+id/box2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/box1"
android:inputType="textMultiLine|none"
android:focusable="false" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/box2"
android:layout_alignParentRight="true"
android:onClick="box2Click" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/encrypt_button_text"
android:layout_below="@id/box2"
android:layout_toLeftOf="@id/button2"
android:onClick="box1Click" />
</RelativeLayout>
答案 0 :(得分:4)
使用示例:
public class main extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.core_info_tab, container, false);
ImageButton ib = (ImageButton) view.findViewById(R.id.imageButton1);
return view;
}
}
答案 1 :(得分:0)
那是因为您在创建片段之前尝试执行setBoxXText(...)
,onCreateView
尚未执行。在访问它的视图之前,请确保已加载您的片段。
如果你检查你的代码,唯一的方法是box1&amp; box2为null是尚未调用onCreateView,所以当你执行
时if(box1 != null) {
box1.setText(text);
}
else {
并且它通过else语句,因为你没有初始化片段。
您有几种方法可以解决此问题,例如,您可以在片段初始化(1)中设置此值,或使用侦听器通知何时加载片段(2)。
1-
使用工厂初始化你的片段,android中的片段需要空构造函数,所以这样你就会使用一个空的构造函数,并确保你自己在onCreateView中设置了box1和box2字符串
public class YourFragment extends Fragment{
//Empty and private constructor
private YourFragment(){
}
private String box1Text;
private String box2Text;
public void setBox1Text(String box1Text){
this.box1Text = box1Text;
}
public void setBox2Text(String box2Text){
this.box2Text = box2Text;
}
public static YourFragment YourFragmentFactory(String box1Text, String box2Text){
YourFragment result = new YourFragment();
result.setBox1Text(box1Text);
result.setBox2Text(box2Text);
return result;
}
}
和2: 当您可以开始设置文本时,使用监听器通知您的活动:
public interface YourFragmentListener{
public void onViewCreated();
}
private YourFragmentListener listener;
public void setListener(YourFragmentListener listener){
this.listener = listener;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
if(this.listener != null){
this.listener.onViewCreated();
}
}
答案 2 :(得分:0)
确保在调用setBox1Text(String text)
之前将片段附加到活动上,否则视图未初始化且getView
返回null。
无需再次初始化edittext。
你可以拥有
public void setBox1Text(String text) {
box1.setText(text); // box1 is already initialized in onCreate no need to initialize again
}
如果您想使用getView
,请在onActivtiyCreated
box1 = (EditText)getView().findViewById(R.id.box1));
答案 3 :(得分:-1)
要使用findViewById
,您必须在Context
执行它(例如Activity
)。
使用:View.getContext().getViewById...
您还可以尝试cleaning the project