void android.widget.ImageView.setEnabled(boolean)' on a null object reference - java

I am using a simple java library file for Undo and Redo text as shown in the tutorial and sample android app but for me when I run the app it shows me the following error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setEnabled(boolean)' on a null object reference
at com.apps.primalnotes.Fragments.EditorFragment.textAction(EditorFragment.java:1023)
at com.apps.primalnotes.Fragments.EditorFragment.onCreateView(EditorFragment.java:84)
Following is the library and method I am following on GitHub enter link description here
And exactly i am doing the following
EditorFragment extends Pantalla implements TextUndoRedo.TextChangeInfo, View.OnClickListener{
private TextUndoRedo TUR;
private ImageView undo, redo;
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.editor, container, false);
getActivity().setTitle("Editor");
setHasOptionsMenu(true);
imm =(InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
base = new DataBase(context, null);
text = (EditText) view.findViewById(R.id.texto);
undo = (ImageView)view.findViewById(R.id.undo);
redo = (ImageView)view.findViewById(R.id.redo);
TUR = new TextUndoRedo(text, this);
textAction(); "Showing error here"
undo.setOnClickListener(this);
redo.setOnClickListener(this);
}
#Override
public void textAction() {
undo.setEnabled(TUR.canUndo()); "Showing error here"
redo.setEnabled(TUR.canRedo());
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.undo:
TUR.exeUndo();
break;
case R.id.redo:
TUR.exeRedo();
break;

Your code doesn't have a "setContentView(R.layout.{file name of layout})".
Could you check it? It should be performed before using findViewById method.

Here the code from the Github source
btn_undo = (Button) findViewById(R.id.btn_undo);
btn_undo.setOnClickListener(this);
btn_redo = (Button) findViewById(R.id.btn_redo);
btn_redo.setOnClickListener(this);
And here the code from your code :
text = (EditText) view.findViewById(R.id.texto);
undo = (ImageView)view.findViewById(R.id.undo);
redo = (ImageView)view.findViewById(R.id.redo);
TUR = new TextUndoRedo(text, this);
The sample using Button for the undo/redo and you using ImageView. Check what is your ImageView ID in xml. Same with other here, your undo/redo ImageView is Null.

Check your XML. Your ImageView for undo & redo should have an id that looks like this,
android:id="#+id/undo
or
android:id="#+id/redo"

Related

No adapter attached; skipping layout / on a null object reference

I was following a tutorial about a comic reading app, and while almost everything works, the last part of my code does not work, it says that my RecylcerView has no adapter attached to it, but it does, and because of that my textview cant be set resulting in a app crash
Here is the fragment.xml where the error happens!
public class fragment_discover extends Fragment implements I_ComicLoadDone {
// Database
DatabaseReference comics;
I_ComicLoadDone comicListener;
RecyclerView recycler_comic;
TextView txt_comic;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_discover,container,false);
// Init Database
comics = FirebaseDatabase.getInstance().getReference("Comic");
// Init Listener
comicListener = this;
loadComic();
// Init List things
recycler_comic = (RecyclerView)rootView.findViewById(R.id.RV_Discover);
txt_comic = (TextView)rootView.findViewById(R.id.comic_title);
return rootView;
}
private void loadComic() {
comics.addListenerForSingleValueEvent(new ValueEventListener() {
List<Comic> comic_load = new ArrayList<>();
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot comicSnapShot: dataSnapshot.getChildren())
{
Comic comic = comicSnapShot.getValue(Comic.class);
comic_load.add(comic);
}
comicListener.onComicLoadDoneListener(comic_load);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(getActivity(), "", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onComicLoadDoneListener(List<Comic> comicList) {
Common.comicList = comicList;
recycler_comic.setAdapter(new MyComicAdapter(getActivity(), comicList));
txt_comic.setText(new StringBuilder("NEW COMIC (")
.append(comicList.size())
.append(")"));
}
}
I didnt put the adapter code in here, because that one works fine, if you need it just ask.
After launching the app I get this error message:
E/RecyclerView: No adapter attached; skipping layout
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
The stacktrace suggests that Your txt_comic TextView is null at the time of calling setText on it. It is caused by the txt_comic not being initialized while the method onComicLoadDoneListener is called after the call to loadComic.
Simply swap the order of txt_comic initialization and the loadComic call:
// Init List things
recycler_comic = (RecyclerView)rootView.findViewById(R.id.RV_Discover);
txt_comic = (TextView)rootView.findViewById(R.id.comic_title);
loadComic();
Second problem is probably the fact, that You are not attaching an Adapter immediately after initializing the RecyclerView. A workaround in Your case would be to pass a null or MyComicAdapter with an empty list:
recycler_comic = (RecyclerView)rootView.findViewById(R.id.RV_Discover);
recycler_comic.setAdapter(new MyComicAdapter(getActivity(), new ArrayList<>())); // or recycler_comic.setAdapter(null);
This should resolve Your problem.

Finding Gridlayout in a Fragment

I have been trying to figure out how to find a Gridlayout in a fragment using findViewById. I've looked everywhere and am surprised to not have found this instructed by anyone in a similar situation of mine. I have used a tab layout in android studios, the tabs are different fragments, and within them are Gridlayouts which have cardviews that open new activities. I have provided the code below to show what I am working with:
public class PCpage extends Fragment {
GridLayout pcGrid;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainPc = inflater.inflate(R.layout.pc_main, container, false);
return mainPc;
pcGrid = (GridLayout) mainPc.findViewById(R.id.pcGrid);
setSingleEvent(pcGrid);
}
private void setSingleEvent(GridLayout pcGrid){
for(int i =0; i<pcGrid.getChildCount();i++){
CardView cardView = (CardView)pcGrid.getChildAt(i);
final int acterI = i;
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(acterI == 0){
Intent intent = new Intent(PCpage.this.getActivity(), Parsecards.class);
startActivity(intent);
}
else if(acterI == 1){
Intent intent = new Intent(PCpage.this.getActivity(), Parsecards.class);
startActivity(intent);
}
});
}
}
}
The following line doesn't seem to want to work out and is returning an error "unreachable statement":
pcGrid = (GridLayout) mainPc.findViewById(R.id.pcGrid);
Any feedback on why this is happening or how to fix this and make it work would be greatly appreciated!
Anything after your return statement will not be executed; the method returns a value and completes. Move the line to somewhere before your return statement.
You are returning mainPc before doing this:
pcGrid = (GridLayout) mainPc.findViewById(R.id.pcGrid);
setSingleEvent(pcGrid);
so just move the return mainPc as the last line in the onCreateView
i think you must put this line :
return mainPc;
after this line :
setSingleEvent(pcGrid);

Get data from firebase DB into string inside my program Android studio

I am trying to retrieve data from firebase DB and save data to a string inside my program. All I come across is that I can only view data in a list but find no good guide how to get data without showing all data for the user first. I want it to be run in the background without the user having to see when data is retrieved. In the image below I show what data I want to store inside a string and then use that string to do what I want it to do.
This is the data I want to store inside my string
You can see the blue rings. The data inside the blue rings is what I want to store inside a string or in a string array.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
firebaseAuth = firebaseAuth.getInstance();
listan = (ListView) findViewById(R.id.listView);
DatabaseReference datarefere = FirebaseDatabase.getInstance().getReferenceFromUrl(My URL to database");
FirebaseListAdapter<String> firebaselist = new FirebaseListAdapter<String>(
this,
String.class,
android.R.layout.simple_expandable_list_item_1,
datarefere
) {
#Override
protected void populateView(View v, String model, int position) {
TextView textview = (TextView) v.findViewById(android.R.id.text1);
textview.setText(model);
}
};
listan.setAdapter(firebaselist);
listan.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView listan = (TextView) view;
String plats = listan.getText().toString();
}
});
toolbar = (Toolbar) findViewById(R.id.tool_bar); // Attaching the layout to the toolbar object
setSupportActionBar(toolbar);
}
In this case i did use listview. The user click on an item inside the list and I save the data to a string. But i dont want to do like that all the time. I want to save data into a string in the background. The user dont need to know or see that it happens.
Maybe something that can help you is this google developer link about how to setup Firebase and other DBs. I hope this helps.

Get an Edittext value of an listview when click on it's item

I have a litview in my code and into each item there is an edittext with a button , So what i want to do is get the edittext's value when press on the button of an listview's item.
I'v tried to get the value by declaring it like this , but it returns null value !
public View getView(int i, View view, ViewGroup viewGroup){
LayoutInflater linflater = getLayoutInflater();
View view1 = linflater.inflate(R.layout.row_view, null);
final EditText replyfld = (EditText) view1.findViewById(R.id.replyfld);
final Button sendreplybtn = (Button)view1.findViewById(R.id.sendreplybtn);
sendreplybtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String thereplyvalue = replyfld.getText().toString();
Toast.makeText(MessagesActivity.this, thereplyvalue, Toast.LENGTH_SHORT).show();
}
});
}
What to do please ?
From the code at pastebin.com/HejVn4bb .
Looks like calling replytogglebtn.setFavorite(false,true); (Line:101) in onClickListener before getting text is the problem because setOnFavoriteChangeListener() clears the edittext.
just get text before the setFavorite(false,true);
You have to do it inside your Adapter. Can you past the code of it?

How can I prevent my findViewById method from being called too early?

So I've got a Dialog, which contains some editText fields (these are spread over 3 fragments, shown by a viewpager, in case this info matters). For an edit action, I want to create that dialog with some values already put in.
At the moment I'm trying to do it like this:
editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GeneralSettingsInitialInputDialog GSIID = new GeneralSettingsInitialInputDialog();
Bundle args = new Bundle();
args.putString("name", TitleTV.getText().toString());
args.putString("ip", IPaddressET.getText().toString());
args.putString("port", PortET.getText().toString());
args.putString("username", UsernameET.getText().toString());
args.putString("pass", PasswordET.getText().toString());
Log.d(tag, args.toString());
GSIID.setArguments(args);
GSIID.show(((Activity) context).getFragmentManager(), "GSIID");
This shows the onClickListener for the edit button (which is contained in a recyclerView. This particular bit comes from my Adapter).
After that, I tried this in the onCreateDialog method for the GSIID dialogFragment:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
ma = (MainActivity) getActivity();
dbHandler = DBHandler.getInstance(getActivity());
view = inflater.inflate(R.layout.fragment_generalsettingsviewpager, null);
mPager = (ViewPager) view.findViewById(R.id.pager);
mPager.setOffscreenPageLimit(3);
mPagerAdapter = new TestAdapter();
mPager.setAdapter(mPagerAdapter);
if (getArguments() != null) {
((EditText) view.findViewById(R.id.IDName)).setText(getArguments().getString("name"));
((EditText) view.findViewById(R.id.IDIPaddress)).setText(getArguments().getString("ip"));
((EditText) view.findViewById(R.id.IDPort)).setText(getArguments().getString("port"));
((EditText) view.findViewById(R.id.IDUsername)).setText(getArguments().getString("username"));
((EditText) view.findViewById(R.id.IDPassword)).setText(getArguments().getString("pass"));
}
// Build Dialog
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(view)
.setTitle("Setup Device")
.setMessage("Please add all required details for your Raspberry Pi here.")
.setPositiveButton("Next", null)
.setNegativeButton("Cancel", null);
return builder.show();
}
This returned a NPE, saying I was trying to use setText on a null, so view.findViewById() is returning null. I thought I'd fix that by moving this code to the onStart() method, to make sure everything is there before I try to set stuff on it, but I'm still getting the same error.
All this time, I'm noticing that the dialog does NOT open before the error occurs, so I'm guessing the findViewById() method is still called too soon, but I don't know how to fix that.
I have tested to make sure my code is not broken, by having the above code run when a button on the GSIID dialog is pressed (so the dialog is opened then). This did indeed work.
So, basically: How can I prevent this findViewById method from being called too early?
Most likely by looking up views in onCreateView() by calling the lookups on the view you're returning from this method.
You need to master the life-cycle of an Activity in android this link and this link can help you to understand the sequence of function calls in each step of the life-cycle.
In most cases you have your views in onCreatView() so it is reasonable to put your findViewById there but in other cases you should make sure the view has been inflated before you call findViewById
Well, my day is saved, thanks to this post.
Basically, you just need a method inside your custom PagerAdapter that returns the view for the index you give it.
CustomAdapter
New: Constructor (I believe that's what it's called)
private View view0 = null;
private View view1 = null;
private View view2 = null;
private View viewError = null;
public TestAdapter(LayoutInflater inflater) {
view0 = inflater.inflate(R.layout.fragment_generalsettingsinputdialog1, null);
view1 = inflater.inflate(R.layout.fragment_generalsettingsinputdialog2, null);
view2 = inflater.inflate(R.layout.fragment_generalsettingsinputdialog3, null);
viewError = inflater.inflate(R.layout.fragment_viewpagererror, null);
}
Changed: instantiateItem()
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View instView = getViewAtPosition(position);
instView.setTag("layoutThingy"+position);
container.addView(instView);
instView.requestFocus();
return instView;
}
New: getViewAtPosition()
public View getViewAtPosition(int position) {
View view = null;
switch(position) {
case 0:
view = view0;
break;
case 1:
view = view1;
break;
case 2:
view = view2;
break;
default:
view = viewError;
}
return view;
}
Other stuff
When initialising PagerAdapter, make sure you pass a LayoutInflater as an argument. For me it was like this: mPagerAdapter = new TestAdapter(getActivity().getLayoutInflater());
Now, I did this in my onStart() method, but I'm guessing you can do this pretty much everywhere.
View page1 = mPagerAdapter.getViewAtPosition(0);
View page2 = mPagerAdapter.getViewAtPosition(1);
View page3 = mPagerAdapter.getViewAtPosition(2);
if (getArguments() != null) {
((EditText) page1.findViewById(R.id.IDName)).setText(getArguments().getString("name"));
((EditText) page2.findViewById(R.id.IDIPaddress)).setText(getArguments().getString("ip"));
((EditText) page2.findViewById(R.id.IDPort)).setText(getArguments().getString("port"));
((EditText) page3.findViewById(R.id.IDUsername)).setText(getArguments().getString("username"));
((EditText) page3.findViewById(R.id.IDPassword)).setText(getArguments().getString("pass"));
}
This properly finds all my EditText's, and should properly find everything I put in my ViewPager. Great! Thanks all for trying to help me, and of course a big thank you to cYrixmorten, with his great post.

Categories

Resources