I got a problem where findViewById() always returns null for the ImageView in my Dialog:
private void startDetailView(int num)throws NullPointerException{
Dialog detailed = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
detailed.setContentView(R.layout.activity_detail_view);
TextView text = (TextView)detailed.findViewById(R.id.detailedTextView);
ImageView picture = (ImageView)findViewById(R.id.detailedImageView);
detailed.show();
/*picture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
final Dialog dial = new Dialog(ScrollActivity.this, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dial.setContentView(R.layout.picture_view);
FrameLayout cont = (FrameLayout)findViewById(R.id.container);
cont.setBackground(getResources().getDrawable(R.drawable.vine));
dial.show();
cont.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
dial.dismiss();
}
});
}
});*/
}
XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/detailedImageView"
android:layout_below="#+id/detailedTextView"
android:layout_centerHorizontal="true"
android:layout_marginTop="134dp" />
The Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.FrameLayout.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at at.tryouts.mcfuckinvineapp.wein.ScrollActivity$1.onClick(ScrollActivity.java:78)
at android.view.View.performClick(View.java:5280)
at android.view.View$PerformClick.run(View.java:21239)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:234)
at android.app.ActivityThread.main(ActivityThread.java:5526)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
This also occurs in the FrameLayout in the second Dialog. Interstingly only these two are affected, I can add any other View without any problem.
I hope you can help me, I can't imagine what's wrong with it.
It may have mistaken Activity view from Detailed view. I bet your ImageView is under Detailed View since it was "layout_below:detailedTextView". Try Changing it to
ImageView picture = (ImageView) detailed.findViewById(R.id.detailedImageView);
Related
This question already has answers here:
findViewByID returns null
(33 answers)
Closed 3 years ago.
This is a basic activity swapping.
The app does not crash if i declare a local button inside the configureActivitySwap() method like this:
Button voiceBtn = (findViewById(R.id.goToVoice));
But I have to declare the button in the global scope instead so I can use the button in other methods, mainly activating and deactivating the button when it should/should not be pressed.
I also noticed that if I remove the finish(); method and replace it with something else the app functions normally, but I have to have the finish(); method one way or another.
public class RecogActivity extends AppCompatActivity {
private Button voiceBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
voiceBtn = findViewById(R.id.goToVoice);
setContentView(R.layout.main_layout);
// some unrelated code
configureActivitySwap();
}
public void configureActivitySwap(){
// Button voiceBtn = (findViewById(R.id.goToVoice));
voiceBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
}
}
My runtime error logs:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: tk.gandriks.gaaudiotransform, PID: 23125
java.lang.RuntimeException: Unable to start activity ComponentInfo{tk.gandriks.gaaudiotransform/tk.gandriks.gaaudiotransform.RecogActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at tk.gandriks.gaaudiotransform.RecogActivity.configureActivitySwap(RecogActivity.java:140)
at tk.gandriks.gaaudiotransform.RecogActivity.onCreate(RecogActivity.java:124)
at android.app.Activity.performCreate(Activity.java:7183)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
You need to call the setContentView() before calling voiceBtn = findViewById(R.id.goToVoice); Since you don't specify the layout the findViewById method will not get the button instance
public class RecogActivity extends AppCompatActivity {
private Button voiceBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the layout first
setContentView(R.layout.YOUR_LAYOUT_XML_FILE_NAME)
voiceBtn = findViewById(R.id.goToVoice);
// some unrelated code
configureActivitySwap();
}
public void configureActivitySwap(){
// Button voiceBtn = (findViewById(R.id.goToVoice));
voiceBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
}
Try I guess) In your // some unrelated code is contains setContentView method?
public class RecogActivity extends AppCompatActivity {
private Button voiceBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
voiceBtn = findViewById(R.id.goToVoice);
setContentView(R.layout.some_layout)
// some unrelated code
configureActivitySwap();
}
public void configureActivitySwap(){
// Button voiceBtn = (findViewById(R.id.goToVoice));
voiceBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
}
}
You caught NPE because of findViewById is calling on inflated view. You are have been calling findViewById before setContentView in the first case and got the exception. And in the second case - in configureActivitySwap, that going after setContentView. Move setContentView after super.onCreate(savedInstanceState) and all will be working fine.
Are you setting layout before trying to find view with findViewById?
setContentView(R.layout.main_layout);
voiceBtn = (Button) findViewById(R.id.goToVoice);
replace the statement in your onCreate() method with the above. It should work.
and use
super.finish() instead of finish()
I'm trying to make my own browser, but I'm stuck. I try to send URL with string as data type using intent from my main activity to the web activity. This is my web activity java code:
public class webView extends MainActivity {
private WebView halamanWeb;
private ProgressBar progressBar;
private EditText searchBox;
private ImageButton tombolCari2;
private String Url;
private String getUrl(){
return Url = "https://" + searchBox.getText().toString();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.surfing_layout);
searchBox = (EditText) findViewById(R.id.searchBoxAtas);
tombolCari2 = (ImageButton) findViewById(R.id.tombolCari);
progressBar = (ProgressBar) findViewById(R.id.bar);
halamanWeb = (WebView) findViewById(R.id.webLayout);
Intent test = getIntent();
final String url = "https://" + test.getStringExtra("key");
halamanWeb.getSettings().setJavaScriptEnabled(true);
halamanWeb.getSettings().setDisplayZoomControls(true);
halamanWeb.setWebChromeClient(new WebChromeClient() {
#Override
public void onProgressChanged(WebView view, int newProgress) {
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(newProgress);
if (newProgress == 100) {
progressBar.setVisibility(View.GONE);
}
halamanWeb.loadUrl(url);
halamanWeb.setWebViewClient(new MyWebLaunch());
}
});
tombolCari2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
halamanWeb.getSettings().setJavaScriptEnabled(true);
halamanWeb.getSettings().setDisplayZoomControls(true);
halamanWeb.setWebChromeClient(new WebChromeClient(){
#Override
public void onProgressChanged(WebView view, int newProgress){
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(newProgress);
if(newProgress == 100){
progressBar.setVisibility(View.GONE);
}
}
});
halamanWeb.loadUrl(getUrl());
halamanWeb.setWebViewClient(new MyWebLaunch());
}
});
}
private class MyWebLaunch extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
}
}
this is my main activity java code :
public class MainActivity extends AppCompatActivity {
//deklarasi
private EditText searchBox;
private ImageButton tombolCari;
private WebView halamanWeb;
private ProgressBar progressBar;
private String Url;
//deklarasi fungsi
private String getUrl(){
return Url = "https://" + searchBox.getText().toString();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchBox = (EditText) findViewById(R.id.searchBoxAtas);
tombolCari = (ImageButton) findViewById(R.id.tombolCari);
progressBar = (ProgressBar) findViewById(R.id.bar);
tombolCari.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Url = getUrl();
Intent test = new Intent(v.getContext(), webView.class);
test.putExtra("key", Url);
startActivity(test);
}
});
}
}
when I run that code, got error code that say:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Can anyone help me with the intent idea, I want to pass a string URL from my main activity to the web activity and then use that to open the site using the URL.
How can I get out from the null pointer on image button?
I would like some help! Thanks!
Edit : This is my log when i start the code, it runs but when i input something and i pressed the ImageButton it crashed.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.johno.myapplication.webView.onCreate(webView.java:54)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Check if you have something like below in your surfing_layout.xml:
<ImageButton
android:id="#+id/tombolCari"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
If it is there, just check if the ID of that image button is tombolCari. If it is something else, just change it to android:id="#+id/tombolCari"
You are overriding MainActivity view with WebView activity and you are expecting MainActivity view should be alive.All your Mainactivity UI elements which are present in R.layout.activity_main will be out of scope.To fix this move to activity_main content to surfing_layout.
Remove setContentView(R.layout.activity_main) and from MainActivity and make surev
surfing_layout has tombolCari imageButton.
Now you have two xml one for MainActivity => "activity_main",
and the second for webView => "surfing_layout".
I see that you extended MainActivity in webView Class and added the same widget and write it again in webView Class, then if you forget to add ImageButton from activity_main.xml to surfing_layout.xml, or forget to add the same id for ImageButton to surfing_layout.xml
Add this code to surfing_layout.xml
<ImageButton
android:id="#+id/tombolCari"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
textView setText() NullPointerException
(3 answers)
Closed 5 years ago.
When I try to setText() on an EditText I keep getting this error, I can't see where I'm going wrong. I'd like to understand the logic behind this error. I'm sure it's something small but it's really bugging me now.
01-25 10:20:44.267
14325-14325/com.example.gregsquibbs.greg_squibbs_todoapp3
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.gregsquibbs.greg_squibbs_todoapp3, PID: 14325
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.gregsquibbs.greg_squibbs_todoapp3/com.example.gregsquibbs.greg_squibbs_todoapp3.EditTodo.EditTodoActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.EditText.setText(java.lang.CharSequence)' on a null
object reference
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual
method 'void android.widget.EditText.setText(java.lang.CharSequence)'
on a null object reference
at
com.example.gregsquibbs.greg_squibbs_todoapp3.EditTodo.EditTodoFragment.setMessage(EditTodoFragment.java:56)
at
com.example.gregsquibbs.greg_squibbs_todoapp3.EditTodo.EditTodoActivity.onCreate(EditTodoActivity.java:41)
at android.app.Activity.performCreate(Activity.java:6975)
at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
This is where I create the etMessage and use setText()
public class EditTodoFragment extends Fragment implements EditTodoContract.View {
private EditTodoContract.Presenter presenter;
private EditText etMessage;
public EditTodoFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_todo_fragment, container, false);
System.out.println("Step 2 - Fragment check");
etMessage = (EditText) view.findViewById(R.id.etMessage);
return view;
}
public void setPresenter(EditTodoContract.Presenter todoPresenter) {
this.presenter = todoPresenter;
}
public String getMessage() {
String message = etMessage.getText().toString();
return message;
}
public void setMessage(String message) {
etMessage.setText(message);
}
}
Here is the XML file
<FrameLayout 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"
tools:context="com.example.gregsquibbs.greg_squibbs_todoapp3.EditTodo.EditTodoActivity">
<EditText
android:id="#+id/etMessage"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="#drawable/rect"
android:ems="10"
android:gravity="top"
android:inputType="textShortMessage" />
<Button
android:id="#+id/bSave"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:onClick="saveButtonClicked"
android:layout_gravity="center_horizontal|bottom"
/>
Here is where setMessage() gets called in the activity
public class EditTodoActivity extends AppCompatActivity {
private String message;
private int position;
private EditTodoFragment editTodoFragment;
private EditTodoPresenter editTodoPresenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_todo_activity);
System.out.println("Step 1");
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.contentFrameContainer);
if (fragment == null){
editTodoFragment = new EditTodoFragment();
fm.beginTransaction()
.add(R.id.contentFrameContainer, editTodoFragment)
.commit();
editTodoPresenter = new EditTodoPresenter(editTodoFragment);
}
message = getIntent().getStringExtra(IntentConstants.INTENT_MESSAGE_DATA);
position = getIntent().getIntExtra(IntentConstants.INTENT_ITEM_POSITION, -1);
editTodoFragment.setMessage(message);
}
public void saveButtonClicked(View v) {
if(editTodoFragment.getMessage().equals("")) {
} else {
String changedMessage = (editTodoFragment.getMessage());
Intent intent = new Intent();
intent.putExtra(IntentConstants.INTENT_CHANGED_MESSAGE, changedMessage);
intent.putExtra(IntentConstants.INTENT_ITEM_POSITION, position);
finish();
}
}
}
Edit: On this line in the fragment
etMessage = (EditText) view.findViewById(R.id.messageField);
When I hover over the casting (EditText) it says
Casting 'view.findViewById(R.id.messageField)' to 'EditText' is redundant less... (⌘F1)
This inspection reports unnecessary cast expressions.
I don't know whether that has anything to do with it or not.
There is no garrenty that editTodoFragment.setMessage(message); will be called after your EditText initialized by this line
etMessage = (EditText) view.findViewById(R.id.etMessage);
In your case your code is setting text to EditText before it's initialized.
Best practice is send data via Bundle to Fragment and set Text after EditText is initialized.
Check this answer
Sample Code:
In EditTodoActivity
message = getIntent().getStringExtra(IntentConstants.INTENT_MESSAGE_DATA);
if (fragment == null){
editTodoFragment = new EditTodoFragment();
//
Bundle bundle = new Bundle();
bundle.putInt(key, message);
fragment.setArguments(bundle);
fm.beginTransaction()
.add(R.id.contentFrameContainer, editTodoFragment)
.commit();
editTodoPresenter = new EditTodoPresenter(editTodoFragment);
}
In EditTodoFragment onCreate
Bundle bundle = this.getArguments();
if (bundle != null) {
message = bundle.getString(key, defaultValue);
}
In EditTodoFragment onCreateView
etMessage = (EditText) view.findViewById(R.id.etMessage);
etMessage.setText(message);
Probably the error is that you have defined etMessage in other file than edit_todo_fragment. That's why you are not getting a compilation error, since the reference to etMessage exists, but it does not exists in your inflated view so thus you got the NPE.
As I understood from logs you're calling setMessage method from onCreate method of your activity. But the problem is Activity's onCreate is called earlier than Fragment's onCreateView, so your EditText is not initialized at that moment.
first you have to define this EditText belong to witch view
then, after you inflate your view you should do this.
View view = inflater.inflate(R.layout.edit_todo_fragment, container, false);
etMessage = view.findViewById(R.id.etMessage);
etMessage.setText("your message...")
if you call set text before it, you see this error
or
this view (etMessage) is not in this layout (edit_todo_fragment)
I have a bunch of fragments in a FragmentPagerAdapter with one ImageView in side each fragment. If I swipe really fast this error comes up:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.wilsapp.wilsapp, PID: 21319
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.wilsapp.wilsapp.Fragments.BuyerHomePageFragment9$DownloadImageTask.onPostExecute(BuyerHomePageFragment9.java:212)
at com.wilsapp.wilsapp.Fragments.BuyerHomePageFragment9$DownloadImageTask.onPostExecute(BuyerHomePageFragment9.java:192)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
If I swipe slowly then it works perfectly fine.
Android Code (code is the same for each fragment. Code in AsyncTask):
protected void onPostExecute(Bitmap result) {
try {
ImageView img = (ImageView) getView().findViewById(R.id.ProductOneImageView);
img.setImageBitmap(result);
}catch (Exception e){
ImageView img = (ImageView) getView().findViewById(R.id.ProductOneImageView);
int id = getResources().getIdentifier("com.wilsapp.wilsapp:drawable/" + "error", null, null);
img.setImageResource(id);
}
}
Android onCreatView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_buyer_home_page, container, false);
return view;
}
how can i avoid the NullPointerException?
ImageView img = (ImageView) getView().findViewById(R.id.ProductFiveImageView);
ImageView need initialize in onCreateView. A case of you getView() return null...
Add your initialization snippet in onViewCreated method instead of onCreateView. it will ensure that imageview will be initialize after your view is inflated.
#Override
public void onViewCreated(final View view, #Nullable Bundle savedInstanceState) {
ImageView img = (ImageView) view.findViewById(R.id.ProductFiveImageView);
img.setImageBitmap(result);
}
ImageView img = (ImageView) getView().findViewById(R.id.ProductFiveImageView);
hi You can add a judgment,getView Whether to null, and Fault tolerant processing!
Answer
The answer / an example can be found at the bottom of this post. The way this answer has been reached, can be found in this answer and its comments.
Original question
I've got a dialogFragment, which has two editText input fields. On a specific buttonClick, I want this dialogFragment to be created, and the two editText fields to be filled with text. For this purpose, I created a simple method inside the dialogFragment's class.
public void presetFields(String nameField, String tagField) {
nameInputField.setText(nameField);
tagInputField.setText(tagField);
}
Problem is, that both nameInputField and tagInputField get initialised inside the onCreateDialog method.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
final View v_iew = inflater.inflate(R.layout.fragment_inputdialog, null);
nameInputField = (EditText) v_iew.findViewById(R.id.inputdialogname);
tagInputField = (EditText) v_iew.findViewById(R.id.inputdialogtag);
}
I thought that would be no problem at all, since I have a similar construction running for a fragment. Only difference is that the editText's get initialised in an onCreateView instead of an onCreateDialog.
This is the onClick code that shows the dialogFragment and calls the method to set the nameInputField and tagInputField fields.
editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stuffManagerInputDialogFragment.show(getFragmentManager(), "TEST");
stuffManagerInputDialogFragment.presetFields(nameTextViewContent, tagTextViewContent);
}
});
When I click the editButton, this is the log I get with the NPE
03-02 16:04:25.120 509-509/com.example.tim.timapp I/art: Not late-enabling -Xcheck:jni (already on)
03-02 16:04:25.190 509-509/com.example.tim.timapp W/System: ClassLoader referenced unknown path: /data/app/com.example.tim.timapp-2/lib/x86_64
03-02 16:04:25.400 509-524/com.example.tim.timapp D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
03-02 16:04:25.520 509-524/com.example.tim.timapp I/OpenGLRenderer: Initialized EGL, version 1.4
03-02 16:04:25.570 509-524/com.example.tim.timapp W/EGL_emulation: eglSurfaceAttrib not implemented
03-02 16:04:25.570 509-524/com.example.tim.timapp W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x7fceb5b27dc0, error=EGL_SUCCESS
03-02 16:04:28.660 509-509/com.example.tim.timapp D/TEST: 2131493026
03-02 16:04:30.310 509-509/com.example.tim.timapp D/AndroidRuntime: Shutting down VM
03-02 16:04:30.310 509-509/com.example.tim.timapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tim.timapp, PID: 509
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
at com.example.fragments.MainFragments.DialogFragments.StuffManagerInputDialogFragment.presetFields(StuffManagerInputDialogFragment.java:149)
at com.example.fragments.MainFragments.VariableFragments.StuffManagerVariableFragment$2.onClick(StuffManagerVariableFragment.java:87)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-02 16:04:33.140 509-509/com.example.tim.timapp I/Process: Sending signal. PID: 509 SIG: 9
I'm not an expert by far, but what I make of this error, is that nameTextView and tagTextView are null at the moment that I'm trying to set text to them, which makes me think the method gets called before the fragment is created.
How can I make sure that both editText's are properly initialised before I try to call something on it?
I have removed some bits of code for easy reading. If something seems to be missing, it probably is. Please let me know, so I can add it.
If you require more code, please also let me know.
Complete answer
All credits go to George Mulligan for this one.
So some stuff has changed from the original approach. First of all, the presetFields method has been removed. The text that should populate the editText fields is now passed to the fragment as an argument.
The onClick method now looks like this:
editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
nameTextViewContent = nameTextView.getText().toString();
tagTextViewContent = tagTextView.getText().toString();
Bundle args = new Bundle();
args.putString("name", nameTextViewContent);
args.putString("tag", tagTextViewContent);
stuffManagerInputDialogFragment.setArguments(args);
stuffManagerInputDialogFragment.show(getFragmentManager(), "TEST");
}
});
So without the presetFields method, we have no way to set the editText fields to the text we want. This has been added to the onCreateDialog method, as can be seen below.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
final View v_iew = inflater.inflate(R.layout.fragment_inputdialog, null);
nameInputField = (EditText) v_iew.findViewById(R.id.inputdialogname);
tagInputField = (EditText) v_iew.findViewById(R.id.inputdialogtag);
if (getArguments() != null) {
nameInputField.setText(getArguments().getString("name"));
tagInputField.setText(getArguments().getString("tag"));
}
}
The null-check for getArguments() has been added because I sometimes need to call this dialogFragment without filling the editText fields. When this happens, it means there are no arguments set to the fragment, which would result in a NPE when calling getArguments().getString("String");
That should be it. I do however have a reputation for being stupid, so it might very well be possible I overlooked something, that should be included in this explanation. If so, please let me know, so I can add it.
What I make of this error, is that nameTextView and tagTextView are
null at the moment that I'm trying to set text to them, which makes me
think the method gets called before the fragment is created.
That is almost correct. The Fragment is created but onCreateDialog() has not been called yet because showing the dialog happens asynchronously after the call to show(...).
You can fix this by adding the two preset Strings as arguments to the DialogFragment.
You can then assign the EditText fields the correct value directly in the onCreateDialog method by using getArguments() on the DialogFragment.
Here is what this looks like:
public MyDialogFragment extends DialogFragment {
private static final String ARG_NAME = "name";
private static final String ARG_TAG = "tag";
public MyDialogFragment newInstance(String name, String tag) {
Bundle args = new Bundle();
args.putString(ARG_NAME, name);
args.putString(ARG_TAG, tag);
MyDialogFragment frag = new MyDialogFragment();
frag.setArguments(args);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
final View v_iew = inflater.inflate(R.layout.fragment_inputdialog, null);
nameInputField = (EditText) v_iew.findViewById(R.id.inputdialogname);
tagInputField = (EditText) v_iew.findViewById(R.id.inputdialogtag);
nameInputField.setText(getArguments().getString(ARG_NAME, ""));
tagInputField.setText(getArguments().getString(ARG_TAG, ""));
}
}
Then the new click event handler.
editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stuffManagerInputDialogFragment = MyDialogFragment
.newInstance(nameTextViewContent, tagTextViewContent);
stuffManagerInputDialogFragment.show(getFragmentManager(), "TEST");
}
});
Don't try to manipulate your dialog immediately after calling show.
If you want to set default values for fields within your dialog, pass them to the dialog as arguments and initialise them during the dialog creation.
e.g
public class MyFragment extends Fragment {
/**
* Static factory method that takes an int parameter,
* initializes the fragment's arguments, and returns the
* new fragment to the client.
*/
public static MyFragment newInstance(int index) {
MyFragment f = new MyFragment();
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}
}
from: http://www.androiddesignpatterns.com/2012/05/using-newinstance-to-instantiate.html