How can I use findviewbyid in static class? - java

I have a static class:
public static void culculateFprice(){
TextView FinalBuy = (TextView) findViewById(R.id.buyText);
int Pprice = MainActivity.pepperoni.getFinalPrice();
int Cprice = MainActivity.calzone.getFinalPrice();
int QCprice = MainActivity.quattrostagioni.getFinalPrice();
int QFprice = MainActivity.quattroformaggi.getFinalPrice();
int Mprice = MainActivity.mexican.getFinalPrice();
int FinalPrice = Pprice + Cprice + QCprice + QFprice + Mprice;
FinalBuy.setText("Стоимось вашего заказа: " + FinalPrice + " руб.");
}
How can I use find findViewById in this class?
I call this method from this method
public static void onPlus(int i){
ArrayList<String> list = listok();
switch (list.get(i)){
...
}
adapteR.refreshData(listokadd());
culculateFprice();
}
And have problem "Non-static method "findViewById(int)" cannot be referenced from a static context"

I assume this function exists in your Activity class and you would like to process some information based on the View. There are two ways you can solve this:
Remove the static modifier and let the instance take care of this.
Create a field that holds a View reference that gets created as soon as your layout is set.
So your Activity will hold the field:
class MyActivity extends Activity {
static View FinalBuy; // needs to be static, otherwise would give same error
}
#Override
void onCreate(Bundle savedInstance) {
// after setLayout
FinalBuy = (TextView) findViewById(R.id.buyText);
}
But to save your code from a potential runtime error, use an if...else block in your static method:
public static void culculateFprice(){
if(FinalBuy != null) {
// your code here.
}
}
This problem is basic Java and not Android. That is how Java language is designed to provide instance vs. static methods for the programs.
This static View declaration leads to a potential design flaw because this View will outlive the Activity. Instead of this, you should consider using the approach I suggested in the list as option 1 and see why you are unable to use an instance method in your program. You should read more on this thread.
This will likely need you to change your other fields of MainActivity to be declared as non-static as well!

Related

What is the best practice for passing object reference to different methods?

First, I would like to thank you in advance for reading/answering my first question on stack overflow. I am new to java (android studio) and struggling a bit with understanding all these objects…
I am building my first app and I have created a new class to store and handle some Tile properties.
What I want, is to instantiate the object once then use a reference to that object and I will pass it to other methods for changing the data inside TileProperties. (I believe this is a good optimization of the memory usage)
I have tried a few solutions that I found but couldn’t make them work fully or couldn’t understand the code.
Here is what I did, which works now but I am wondering if it’s the best practice and also if it's a good option for the future:
public class TileProperties {
private String length ;
private String width ;
public static TileProperties object; // I created a static object TileProperties
// which I use to pass the reference
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
The code below shows my activity class where the user enters all the properties
Also, its where I initiate my object Tiles
public class TileSettingActivity extends AppCompatActivity {
TileProperties tiles = new TileProperties();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tile_setting);
}
public void clickOkButton (View view) {
TileProperties.object = tiles; // save the object reference tiles to be used by others
EditText lengthTile = findViewById(R.id.editText2);
tiles.setLength(lengthTile.getText().toString());
Log.i("Length:", tiles.getLength());
}
And then in my main activity I wrote this:
public class MainActivity extends AppCompatActivity {
public void clickScanButton(View view){
TileProperties obj ; // define object reference
obj = TileProperties.object; // get the reference of the orginal object Tiles
Log.i("info:", obj.getLength());
}
Thank you!!
No this is not "best practice". It is not even "good practice". It is arguably wrong. Certainly it would be wrong in a larger application.
Let's start with this class:
public class TileProperties {
private String length ;
private String width ;
public static TileProperties object; // I created a static object TileProperties
// which I use to pass the reference
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
}
In order of least important to most important, the problems are:
There are various style issues. The most important are that the indentation is incorrect and your choice of object for a variable name is bad. Variable names should convey relevant meaning to the reader.
Documentation. The comment // I created a static object ... should be a proper javadoc comment, that describes the purpose of this (public !) variable.
Public variables break encapsulation and encourage excessive coupling. They are not Object Oriented. They should be avoided.
Public static variables are worse because they also represent global state.
If you are going to implement a single shared "properties" object for the application, there are three ways to do it.
You can create a single instance of the class and pass it as a parameter to all of the parts of the application that need it. This can be clumsy if you have to pass the reference to lots of places.
You can use the Singleton design pattern. A simple example for your use-case would be:
public class TileProperties {
// state variables
private static TileProperties instance = new TileProperties();
private TileProperties() { } // This prevents creation of multiple
// instances of the "singleton"
public static TileProperties getInstance() {
return instance;
}
// getters and setters for state variables, etc.
}
// In main
TileProperties props = TileProperties.getInstance();
props.setLength(42);
There are other ways to implement singletons in Java; e.g. if the singleton needs to be initialized lazily.
Use Dependency Injection (DI).
Dependency injection is considered to be superior to Singleton classes in large-scale applications because singletons present problems for unit testing. However, DI requires a framework such as Spring to implement the injection. That is a whole new learning curve.

Calling external methods without instantiating an object

I was wondering if it was possible to call the methods of an external class without actually having to declare an object of that class. They way I've got it set up causes the ArrayList stored within the object empties every time the method the object is used in is called.
If I can call the method without an object, then I can fix my problem.
Thanks in advance.
calling class:
public class BookingScreen extends Activity {
GAClass sendApplication = new GAClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_booking_screen);
}
public void saveBookingInfo(View view) {
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
this.finish();
}
}
External method class:
public class GAClass {
ArrayList<Application> peopleAttending;
public void storeApplication(String name, String item){
peopleAttending = new ArrayList<>(10);
peopleAttending.add(new Application(name, item));
}
}
You can do something like below
public class GAClass {
public static ArrayList<Application> peopleAttending=null;
public static void storeApplication(String name, String item){
if(null==peopleAttending){
peopleAttending = new ArrayList();
}
peopleAttending.add(new Application(name, item));
}
}
You can invoke above method like below
GAClass.storeApplication(str_name,str_item);
when you make peopleAttending arraylist static it can be access in static method and
if(null==peopleAttending){
peopleAttending = new ArrayList();
}
Above code ensure first time initialization if peopleAttending 9s null
Use static methods. You can call a static method without creating object of enclosing class.
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
What exactly are you trying to achieve?
The static methods in a class would not need an instance of the class so you can make the methods you need (that do not require the state of the object - i.e. do not need a particular object to work on) static and call them like this:
ClassWithStaticMethods.staticMethod() ;

Visibility of a variable after changing its location

I have a basic question in Java:
Consider I have
public void initialize(My_Class my_context) {
super.initialize(my_Context);
}
public void work(My_Class2 elt) {
String text = elt.getText();
My_Class3 var1 = new My_Class3();
String new_text = var1.my_method(text);
I am having a problem because I am calling the work method many times, and each time it instantiates a My_Class3 object, which takes a lot of time. I would like to move the instantiation in the initialize method so that it is performed once.
In order to do that, I tried to move
My_Class3 var1 = new My_Class3();
into initialize and set it as a global variable so that var1 is found in the different calls of work. However, I cannot set it into a static variable. I am guessing this has something to do with the visibility of the initialize method, but I cannot change it.
How can I instantiate a var1 variable of type My_Class3 in initialize and call it in work?
My_Class3 var1;
public void initialize(My_Class my_context) {
super.initialize(my_Context);
var1 = My_Class3();
}
public void work(My_Class2 elt) {
String text = elt.getText();
String new_text = var1.my_method(text);
}

Android Studio Unknown Class

When I declare double variables, and later try to assign values to them, it says unknown class . Secondly, any method calls from objects I have created say cannot resolve symbol .
My code:
private double xCurrentPos, yCurrentPos;
private ImageView test = (ImageView) findViewById(R.id.square);
xCurrentPos = test.getLeft();
yCurrentPos = test.getTop();
This code says that xCurrentPos and yCurrentPos are both unknown classes and that it cannot resolve getLeft or getTop.
Any help would be greatly appreciated. :)
You can't do assignments of variables like that in the context of the class.
From what I can tell you're doing something like this which gives you the errors you described.
public class YourActivity extends Activity {
private double xCurrentPos, yCurrentPos;
private ImageView test = (ImageView) findViewById(R.id.square);
xCurrentPos = test.getLeft();
yCurrentPos = test.getTop();
...
}
You would have to do the assignment as they are being declared like this:
private int xCurrentPos= test.getLeft();
private int yCurrentPos = test.getTop();
Or you do the assignments within an actual method.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
xCurrentPos = test.getLeft();
yCurrentPos = test.getTop();
}
Second, doing this:
private ImageView test = (ImageView) findViewById(R.id.square);
will not work anyway as this will get initialized before onCreate so test will be null.
Even doing this in onCreate after you set the content view will give you values of 0 for both getLeft and getTop as the your views have not been drawn yet. For that you can refer to this. You basically need to do it in an event where you views have already been drawn.
The View class's getLeft() and getTop methods return an int, not a double. You don't need to use double type.

Problem accessing variable[] from another class

I know this a pretty basic question, and already found another ones like mine, but I honestly don't know what I'm doing wrong.
public class InteractiveArrayAdapter extends ArrayAdapter<Model> {
private final List<Model> list;
private final Activity context;
public int teste;
public InteractiveArrayAdapter(Activity context, List<Model> list) {
super(context, R.layout.rowbuttonlayout, list);
this.context = context;
this.list = list;
}
public int getTest()
{
return teste;
}
static class ViewHolder {
protected TextView text;
protected CheckBox checkbox;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
teste = 2;
....
}
}
and other class:
try{
InteractiveArrayAdapter adapt = new InteractiveArrayAdapter(this,
getAPPS(0));
int test = adapt.getTest();
Toast.makeText(this, Integer.toString(test), Toast.LENGTH_LONG).show();
Log.v("TAG",Integer.toString(test));
}catch(Exception e)
{
Log.v("EXCEPTION",e.toString());
}
EDIT: I was getting null for a stupid mistake, and now I'm getting the primitive and expected 0 as most of you say.
At some point of my app, everytime a checkboxes is clicked that method getView is executed. I want to store that to an array[] of strings progressively (i+1) (i just put int to be easier to understand - realize now it was a mistake), and then when users inputs ok I want to access the whole array. Wondering if it's possible the way I want.
So when I do this
InteractiveArrayAdapter adapt = new InteractiveArrayAdapter(this,
getAPPS(0));
This is meaningless, because I don't need to execute anything again, I just want to retrieve the created array - if possible!
Your code won't even compile. return this.teste; should be return this.test;.
Well, this isn't a direct copy/paste, since this obviously wouldn't compile. Whenever you're dealing with an actual error or issue, it's really best to paste the actual code. We're all programmers, so we can read it.
But based on the structure you've shown above, either the typo you've put in the line return this.teste (should be return this.test) is in your code, or you didn't initialize the instance variable test in your constructor.
Without showing us the actual code you're writing, it's impossible to say (especially the section that initializes the test variable, and the part that returns its value are missing - we're not mind readers, I'm afraid).
So, those are two potential candidates. On another note, however, if you mark the test variable as public, then you don't need to have getter/setter methods for them, since any class can access them without going through a method call. That's what public does.
But that is what should happen according to your code. You don't call B method to update teste variable.

Categories

Resources