Why is findViewById undefined in my class? - android

I have a class and inside the class I try to call the findViewById method but I am getting an error saying findViewById is undefined.
I think I have to pass the WebView to MyClass or something but I have no idea on how to do that.
Here is the code i am working on:
public class MyClass {
Context mContext;
MyClass(Context c) {
mContext = c;
}
...
WebView webview = (WebView) mContext.findViewById(R.id.myWebview);
webview.loadUrl("mysiteUrl");
...
}
public class MainActivity extends Activity {
final myClass mc = new myClass(this);
...
}
I know that this is happening because MyClass does not extend an Activity. However I can get the WebView without extending Activity...
Please help! Thanks.

findViewById is a method that is defined by Android. Therefore you need to actually extend an Android Activity like so for it to recognise it as a method:
public class MyClass extends Activity {
and then import Activity when prompted.
If you want to utilise findViewById in a non-Android Activity then you can specify an Activity for it to find the view in like so:
WebView webview = (WebView) OtherActivity.findViewById(R.id.myWebview);

Related

Is it okay to extend to MainActivity from a JavaScriptInterface to avoid non-static errors?

I have one activity with a webview in it.
When the user interacts with the webview, it does this through the JavaScriptInterface so both the app and webview can interact with each other.
I believe the class is by default static, so I've found not too much can be done without it extending MainActivity.
public class JSInterface extends MainActivity {
private MainActivity mainActivity;
JSInterface(Context context, MainActivity mActivity) {
mainActivity = mActivity;
}
#JavascriptInterface
public void someMethod() {
mainActivityMethod(webViewData);
}
// other methods
}
In my MainActivity I have:
WebView webView = findViewById(R.id.webView);
JSInterface JSInterface = new JSInterface(this, this);
//other methods called by JSInterface, e.g.
#Override
public void mainActivityMethod(String webViewData) {
// do something with data
}
So I've found by extending to MainActivity from JSInterface, I can call normal (non-static) methods from MainActivity which is very much a necessity.
If I don't extend it to MainActivity, it seems to be a static class and I get this error when trying to call MainActivity methods or reference anything not static:
Non-static method someMethod() cannot be referenced from a static context.
It works as it is, but I feel like this isn't the best way to go about it.
Am I right?
What would be the 'best' way to do this? Or other ways, as best is subjective.
I feel like this isn't the best way to go about it
Never create a subclass of Activity unless you are going to start it with startActivity().
What would be the 'best' way to do this?
One option is simple composition, getting rid of the improper inheritance:
public class JSInterface {
private MainActivity mainActivity;
JSInterface(MainActivity mActivity) {
mainActivity = mActivity;
}
#JavascriptInterface
public void someMethod() {
mainActivity.something(webViewData);
}
// other methods
}
Another is a nested class. In this sample activity, Locater is a nested class inside of my GeoWebOne activity, and therefore Locater can call methods and access fields in GeoWebOne. The simple composition approach is a better answer, though a nested class will work.

findViewById in non activity class

I know there are some topics in StackOverFlow asking this But all of them are answering in special cases No one answers this question generally.
Can anyone say how to use findViewById in non activity classes?
For Example in my case I want to define a webview:
WebView view=(WebView)findViewById(R.id.webview);
But I can't and I really don't understand why android makes everything complicated.Why you can use everything in main activity but you can't use many of them in non activity class :(
UPDATE
I can't extend my class as activity cause it extends sth else.
UPDATE
This is the class:
class DownloadTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... sUrl) {
...
WebView view=(WebView)findViewById(R.id.webview);
final Snackbar snackbar = Snackbar.make(view,"message",Snackbar.LENGTH_LONG);
...
}
}
I'm gonna use the webview in a Snackbar.
Can anyone say how to use findViewById in non activity classes?
Pass the activity into the method you are calling on the non-activity class.
Or, pass the activity into the constructor of the non-activity class.
Or, call findViewById() in the activity and pass the WebView to the non-activity class.
Plenty of other patterns exist. You need to be careful that you do not try using the activity or WebView longer than you should (e.g., after the user rotates the screen, presses BACK, or otherwise causes the activity to be destroyed).
I'm gonna use the webview in a Snackbar.
Using a Snackbar is fine. Using one from an AsyncTask is not, unless you do so very carefully. In particular:
Only try doing this from the main application thread (i.e., not doInBackground())
Make sure that you are handling configuration changes, BACK presses, and the like properly. In particular, you cannot show a Snackbar on a destroyed activity
1-in non activity class:
public Context con;
public NonAct(Activity c){//NonAct = your non activity class name
this.con = c;
}
//in your class or function do this:
WebView view=(WebView)con.findViewById(R.id.webview);
2-call non activity class with sending context argumant:
NonAct n = new NonAct(YourActivity.this);
try this
ClassName instance = new ClassName(this);
and starting of your class will look like this
public class ClassName extents to something {
public Activity activity;
//.... other attributes
public ClassName( Activity _activity){
this.activity = _activity;
//other initializations...
you can use findviewby id like this
WebView mywebview = (WebView)this.activity.findViewById(R.id.mywebview);
///// now do whatever u want
i hope this will help u.
just look at this link u have to pass your view inflated to AsyncTask
findviewbyid in asyncTask

setOnClickListener for a button

Just getting started with Android development and I can't figure out why this won't work. Here is the error that I am getting (on the last line):
The method setOnClickListener(View.OnClickListener) in the type View
is not applicable for the arguments (MainActivity)
And here is the code. Seems pretty simple, but I don't see what the problem is. Can anyone help? Thank you!
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_myActivity);
View continue = findViewById(R.id.ContinueBtn);
continue.setOnClickListener(this);
}
}
Try this.
public class MainActivity extends Activity implements OnClickListener
When you pass this object into setOnClickListener then you need to implement OnClickListenere .
you have to do like this
public class MainActivity extends Activity implements OnClickListener {
/// code
}
first of all change the continue to some other name as it is the keyword you can't give a keyword as variable name
implements OnClickListener for your Mainactivity
Button continuea = (Button)findViewById(R.id.ContinueBtn);

using findviewbyid in a class that does NOT extend Activity in android

I have a class that is currently extending Activity and I have methods like findViewById, ArrayAdapter etc.
I want to turn it into an independent class but all the above methods become undefined. What is the problem? Shouldn't importing the classes be enough? For eg, I import android.view.View for findViewById but it still makes no difference.
Please advise.
you should pass the instance of your Activity to your Second Class on the constructor like this :
In your Activity Instanciate your Class like this :
MyClass instance = new MyClass(this);
And in your second Class , the constructor will be like this :
public class MyClass {
public Activity activity;
//.... other attributes
public MyClass( Activity _activity){
this.activity = _activity;
//other initializations...
}
}
and then when you want to use the findViewById() method , you can do like this :
EditText txt = (EditText)this.activity.findViewById(R.id.txt);
if you want to call any function that belongs to Activity then only thing you need to have is context of the Activity.
eg.
class A extends Activity {
Context ctx;
void onCreate(Bundle b)
ctx = this;
B bob = new B(ctx);
}
}
Here is class B.
class B {
B (Activity a) {
a.anyFunctionOfActivity();
}
}
findViewById is non-static public method of the Activity Class ,so it only be available for a Activity object. Therefore, import android.view.View and android.app.Activity won't make it available. To make it available, you could pass around a Actvity object - usually a this point in your activity. However, notice that you should always update your View in the UI thread.
Please try the following:
public static View getLayoutByRes(#LayoutRes int layoutRes,#Nullable ViewGroup viewGroup)
{
final LayoutInflater factory = getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return factory.inflate(layoutRes, viewGroup);
}
TextView tv = (TextView) getLayoutByRes(R.layout.xxx ,Null).findViewById(R.id.editd);

How to use setContentView(int) from class which does not extend Activity

I need to call the setContentView(int) from my main Activity from another class which does not extends Activity.
In my custom class I've got the private Context context; var that is passed from the Activity in the Constructor but I can't figure out how to acces the Activity methods using the context variable.
If your context is an instance of Activity class, simple class cast should work:
Activity a = (Activity) context;
a.setContentView(R.layout.your_layout);
One solution (may not be the most elegant) is to pass the calling activity to the other class, not just the context.
You would have to pass in a reference to the Activity you're using.
Something like this
class ActivityA extends Activity{
#Override
public void onCreate(Bundle state){
super.onCreate(state);
ClassA myclass = new ClassA(this);
}
}
And then Class A would have:
class ClassA {
public ClassA(Activity yourActivity){
... Get your view here ....
yourActivity.setContentView(view);
... do more things...
}
}

Categories

Resources