Error replacing ButterKnife annotation with native ViewBinding - java

I'm refactoring a lot my app activities and layouts (e.g. ButterKnife annotation -> viewBinding, *Layout --> ConstraintLayout). For a lot of them there were no problem, but at the moment I'm stuck in this situation of my Activity:
Original code:
...
#BindView(R.id.logged_user)
TextView mUserLoggedView;
#BindView(R.id.patient_code)
EditText mPatientCodeView;
#BindView(R.id.search_form)
ScrollView mFormView;
#BindView(R.id.search_progress_layout)
LinearLayout mProgressLayout;
#BindView(R.id.search_progress_text)
TextView mProgressTextView;
App application;
SearchActivityMapper mapper;
CompositeDisposable mCompositeDisposable;
#Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_search_patient);
ButterKnife.bind(this);
application = (App) getApplication();
application.getAppComponent().inject(this);
...
Code after review:
...
App application;
SearchActivityMapper mapper;
CompositeDisposable mCompositeDisposable;
#Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
viewBinding = ActivitySearchPatientBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot());
ButterKnife.bind(this);
application = (App) getApplication();
application.getAppComponent().inject(this);
...
I did the same in all the previous Activity and everything went well; when the latter Activity is launched I got this error
java.lang.NoSuchFieldError: No field mUserLoggedView of type Landroid/widget/TextView; in class Lit/company/etmhome/activities/search/SearchActivity; or its superclasses (declaration of 'it.company.etmhome.activities.search.SearchActivity' appears in /data/data/it.company.etmhome.debug/code_cache/.overlay/base.apk/classes27.dex)
I can't understand why it can't find that field that I removed and it's not present in the whole project.
Am I missing something???
Thanks in advance

Related

How to correct add a listener to a Fragment

I got two Fragments (basic-setup) with a FragmentPagerAdapter for use in a TabLayout.
tabLayout.setupWithViewPager(myViewPagerWithAdapter);
My Adapter takes an array of Fragments and titles as argument (also the FragmentManger for the super call).
MyViewPagerAdapter adapter = new MyViewPagerAdapter(getSupportFragmentManager() ,fragments, titles);
My Fragments (indeed 2) got a WebView in their xml file. To use the WebViews outside the fragments (it's kinda odd to code the control of the WebViews inside fragments, because the MainActivity is mainly involved with my user interaction). To know when my WebViews in the fragments were inflated, I added a simple interface, called OnFragmentCreatedListener, which is triggered in public void onActivityCreated(Bundle savedInstanceState) of the fragments. I add the listener through following way:
private OnFragmentCreatedListener listener;
...
public void addOnFragmentCreatedListener(OnFragmentCreatedListener listener) {
this.listener = listener;
}
In my MainActivity I add this listener like this:
public class MainActivity extends AppCompatActivity implements OnFragmentCreatedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
MyFragment fragment = MyFragment.newInstance();
...
fragment.addOnFragmentCreatedListener(this);
...
}
#Override
public void onFragmentCreatedListener() {
// Do my stuff
}
Now when the screen rotates and the activity is restarted, the listener in the fragment stays null (wasn't initialized). Now I don't know what to do, because I don't understand this behavior. The code should do the same like in the first protected void onCreate(Bundle savedInstanceState) of the MainActivity. It's adding the listener but it stays null (like wtf?).
Thank you for spending your time!

Android wear - WatchViewStub deprecated

I am trying to build an Android Wear app. When I start new project with APK 23 (Marshmallow) and above, the default code I get with the new project are as follows;
public class MainActivity extends Activity {
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener()
{
#Override
public void onLayoutInflated(WatchViewStub stub)
{
mTextView = (TextView) stub.findViewById(R.id.textView);
}
});
}
}
But according to a Android blog, WatchViewStub class is deprecated from API 23 (Marshmallow). According to the blog files rect_activity_main.xml and round_activity_main.xml are replaced by one layout file. But my problem is even when I start a new project with newer APIs I still get the deprecated classes and files (XMLs) in my project. According to the blog, this is how the new default code should look like in main_activity.java;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text);
}
How do I fix this? Please comment before down voting. I have tried a lot of things around the web; Asking at stack overflow was my last resort.
I solved this problem by using one of Android studio's skeleton projects. Then amend the code as needed. I am not still sure how to do this by default when we open a new project.

Extending library activity doesn't call onCreate

I have added a project 'A' as library in my project 'B'. Now in project 'B', I have an activity 'MainActivity' which extends an activity 'SplashActivity' of project A.
When i'm running the app, the onCreate of 'MainActivity'(Project B) is never called, rather the OnCreate of 'SplashActivity'(Project A) is called every time. What could be the problem?
Also what if I want to call the onCreate method of 'SplashActivity'(Project A) and then the onCreate of 'MainActivity'(Project B), is it possible?
The code is given below:
public class MainActivity extends SplashActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_activity_temp);
new SplashActivity().setLogo();//never called
}
}
change your xml ref
setContentView(R.layout.activity_splash_activity_temp);
new SplashActivity().setLogo();
to
setContentView(R.layout.activity_main);
SplashActivity splashactivity = new SplashActivity();
splashactivity.setLogo();
I solved my own answer ,and thanks to #jimit patel and # ρяσѕρєя K , I solved it and and if anyone looking for an answer
Code :
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_splash_activity_temp);
ImageView imageView = (ImageView) findViewById(R.id.splash_logo);
super.setLogo(imageView,this);
super.onCreate(savedInstanceState);
}
Just call the super.onCreate at the end of the code , and the code will work just as expected . :)

v7 getSupportActionBar() is throwing NullPointerException

I'm launching a new activity (TVMPDFActivity) from my root activity. I'm using Android Annotations, so this is how I'm launching the Activity:
TVMPDFActivity_.intent(this.getActivity()).start();
TVMPDFActivity is a subclass of PDFPreviewActivity which is a subclass of ActionBarActivity.
A NullPointerException is being thrown from onCreate in PDFPreviewActivity when I simply try to GET the ActionBar. On this line:
final ActionBar actionBar = getSupportActionBar();
Here is the stacktrace from my code to the NPE:
Caused by: java.lang.NullPointerException
at android.support.v7.internal.app.WindowDecorActionBar.getDecorToolbar(WindowDecorActionBar.java:248)
at android.support.v7.internal.app.WindowDecorActionBar.init(WindowDecorActionBar.java:201)
at android.support.v7.internal.app.WindowDecorActionBar.<init>(WindowDecorActionBar.java:176)
at android.support.v7.app.ActionBarActivityDelegateBase.createSupportActionBar(ActionBarActivityDelegateBase.java:156)
at android.support.v7.app.ActionBarActivityDelegate.getSupportActionBar(ActionBarActivityDelegate.java:123)
at android.support.v7.app.ActionBarActivity.getSupportActionBar(ActionBarActivity.java:73)
at com.my.app.PDFPreviewActivity.onCreate(PDFPreviewActivity.java:63)
at com.my.app.TVMPDFActivity.onCreate(TVMPDFActivity.java:24)
at com.my.app.TVMPDFActivity_.onCreate(TVMPDFActivity_.java:31)
Here are the onCreate methods of the various classes involved:
public class TVMPDFActivity extends PDFPreviewActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
this.setContentView(R.layout.tvm_pdf_activity);
super.onCreate(savedInstanceState);
...
}
}
public abstract class PDFPreviewActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar(); // throws NullPointerException
...
}
}
Why am I getting a NullPointerException from deep within the support v7 code?
you should call super.onCreate before setContentView in TVMPDFActivity in order to give android the opportunity to initialize its internal state, before trying to access something that relies on that internal state. For onCreate/onStart/onResume call the super always as first statement

App crashes when setting layout background

I'm trying to set a drawable resource as background for my main relative layout via java, but whenever I do it, my app crashes.
Here is the part of the code which doesn't work fine:
public class GameActivity extends Activity {
RelativeLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = (RelativeLayout) findViewById(R.layout.activity_game);
setContentView(R.layout.activity_game);
layout.setBackgroundResource(R.drawable.image);
}
}
Any idea?
Thanks in advance
Call findViewById() only after setContentView() and supply an identifier in R.id (and not R.layout) so that it can return something other than null.
Remember,you are trying to find a view by id but what you are doing is actually trying to inflate a layout the wrong way.Change the R.layout.activity_game to R.id.activity_game and make sure the relative layout is givent the
android:id = "#+id/activity_game"
The full code should be
public class GameActivity extends Activity {
RelativeLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
layout = (RelativeLayout) findViewById(R.id.activity_game);
layout.setBackgroundResource(R.drawable.image);
}
}
Hope it helps.Happy coding.

Categories