Android studio, subclass of AppCompatButton does not act like a button - java

I am working on an android app in java, and ive created a sub-class of android.support.v7.widget.AppCompatButton, because youre not supposed to directly subclass Button. When i create the subclass object (hencforth refered to as "subButton") and add it to the activity via XML, the item looks and acts like a button, however when i do so via Java (programatically) , it looks and acts like a textView instead.
my XML is
<com.example.appName.subButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="xmlTestItem"/>
While my Java is
subButton testItem = new subButton(getApplicationContext());
testItem.setText("javaTestItem");
testItem.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT ,ViewGroup.LayoutParams.MATCH_PARENT));
mainListScroll.addView(testItem);
but it still only displays text instead of a button. Any clues?

The issue is most likely caused by the use of the application context rather than activity context when instantiating the subButton instance. In particular, the themes associated with these contexts, which are used when instantiating view components, are usually different.
As a general rule you should use the context directly available to you at the time. In an activity, this means making use of its own context via this.
For more details, see this classic post: https://stackoverflow.com/a/7298955/2259854

Related

Java: Interaction/connection of Android UI (Android Studio) and java backend (model) (in comparison to JavaFX)

I'm quite new to programming and started with Java, went to JavaFX as GUI development and just tackled Android App Development with Android Studio.
Coming from JavaFX and its concept of having the UI connected to a backend controller I am a bit confused about the (apprently) much more complex interaction of Android UI with the Java backend (controller, model).
My scenario: I programmed a game application with JavaFX which works quite fine. I applied the MVC concept whereas I used FXML to construct the UI, had a Controller.java class which "connected" all UI elements via #FXML to my controller class and then I could - cross-method within the controller - access my UI elements (e.g. for reading values from sliders, or changing them), like:
#FXML
private text label;
public void readLabel(){
String labelText = label.getText();
}
Now: In Android (using Android Studio) I tried to apply the same concept/idea but failed because obviously the various views, buttons, texts respectively have their own classes which need to be casted to one another so that their content can be used.
So I followed the Android concept and tried to initially declare all UI elements within the MainActivity class as follows:
public class MainActivity extends AppCompatActivity {
EditText inputText = (EditText) findViewById(R.id.text1);
EditText outputText = (EditText) findViewById(R.id.textOutput);
Button enterButton = (Button) findViewByID(R.id.button1);
...
This is because I want to reuse (simply access/change) them in different methods within the MainActivity.
The above approach failed due to a NullPointerException. I tried to initialize the respective objects with, e.g.:
Button button1 = new Button();
but this didnt work either.
However if I use above approach WITHIN a method of the MainActivity, it works fine:
public class MainActivity extends AppCompatActivity {
public void enterMessage(View view){
EditText inputText = (EditText) findViewById(R.id.text1);
String textOutput = inputText.getText().toString();
EditText outputText = (EditText) findViewById(R.id.textOutput);
outputText.setText(textOutput);
}
and I can read and change my UI objects.
I then had the idea of making a static "controller method" within the MainActivity so that I can access my UI elements from any other method within my MainActivity. But this dindnt work out because
findViewById()
doesnt go along with static methods.
So the only way I see right now after trying these different approaches, is to create new objects and cast them to the required variable, like:
EditText inputText = (EditText) findViewById(R.id.text1);
String textOutput = inputText.getText().toString();
in EVERY method which I want to create within the MainActivity.
Now my question: Is the concept with the Android UI classes indeed that more complex in comparison to JavaFX or do I just get it wrong somewhere with the basics? Any hint for a best practice is much appreciated. :)
Thank you!
What is way more complex is the lifecycle of the views inside the Android Application. In Java's Swing for instance there's no such thing as lifecycle of a view/controller and I don't know about JavaFX. The underlying platforms are not the same although the programming languages are.
Android comes from a context where devices barely had any available memory and very little computational power. For that, Android tries to save as much resources as it can.
You must listen for the Activities lifecycle events since they may affect whether your View objects are still there or not. For instance: You may have your MainActivity instance running but by simply turning the phone in landscape mode makes your current MainActivity die and get a new instance with the updated View.
So you'll find yourself writing lots of findViewById during your Android App Development. But there are solutions to make Android development a little bit easier.
By seeing your experience with #FXML I would suggest you take a look to ButterKnife which is an annotation processor that takes care of findingViewById for you and it may help you a lot. Looks like the way of consuming the views is similar
Also take a look to Android's Architecture components since they leverage a lot of boilerplate code and allow you to focus on what you want to write. Specially DataBinding
I would also strongly suggest you take a look into Kotlin, since it runs on the JVM and you can use it both for Android and Java development. Turns out it is a really fun language to use and quite efficient speaking in terms of the amount of code you have to write to get something done.
Thanks #Some random IT boy for guidance.
Actually my problem/confusion is solved now. What I can recommend, in order to have a much more simplified GUI-backend interaction is to use the new View binding feature.
View binding (https://developer.android.com/topic/libraries/view-binding) is available in Android Studio 3.6 Canary 11+. Right now this means to install the pre-final version of Android Studio but with that it works just fine.
View binding is a standardized feature which actually provides similar functionality as Butter Knife. As per the Butter Knife website "view binding" appears to be the feature-wise successor.
The instructions of how to use view binding are included in the link above. Following the steps there lets you interact with Android GUI similarly to the approach in JavaFX.

android -what approach to be used for some java code that repeats in many activities

I have an app that has a top menu as shown in the fig below. This is almost constantly used in all activities. For layout I have defined it in a single xml file and use <include>to include it in every layout file.I want to know if there is a way in java coding to avoid declaring all the imageButtons, and then using findViewById and onclick events for them , in each activity. The top four icons will act as menu and be available in all layouts and activities
First of all, what you are trying to achieve is against the android standards and this could affect the user experience for Android users. Instead, add the menu items on the action bar.
Anyway, you can achieve what you are looking for by defining a base class (named it like ActivityBase) and do all the initializations and listeners registrations on it. Then, extend from that base class. Bear in mind that each activity will have its own instance of the views of the base class and the state will differ from activity to another.
Although you have accepted an answer I disagree that the Application class should be used to host global methods. It can be used for maintaining global state but that's a different matter.
As others have said, use inheritance by creating a base Activity class then extend that for all of your other Activities. To make things easier, however, you can define the onClick method to be used for each of your buttons in the layout file itself by using (for example)...
android:onClick="myOnClickMethod"
As long as the base Activity defines a public method called myOnClickMethod (or whatever method name you choose) with a void return and which accepts a View parameter it will work without the need to implement View.OnClickListener and without having to set the listener in Java code. Example
public class MyBaseActivity extends Activity {
public void myOnClickMethod(View v) {
// Get the resource id of v and use switch / case to perform action needed
}
}
That's all you need.
Write it only in the first activity. Extend it to the other activities instead of extending with android.app.Activity.
Eg:
public class SecondActivity extends MainActivity{
}
Put that method in MyApplication class which extends Application. So, that it can be accessible by multiple activities.

Why do i have to cast a Button?

This must be a really dumb question because I cant find an answer online.... I know that casting is changing one datatype to another. How is this button ever changing it's data dype? Button button = (Button)findViewById(R.Bla.Bla) Why cant we just write Button button = New Button() And then assign the xml to it another way? Please explain, I'm lost.
You can set a Button to a new button.
But findViewById returns a view. If you want to access any of its Buttonosity, you must cast, otherwise the reference isn't a button. There are times that may be okay, of course.
See In Android You can create the UI Elements in two ways:
1. create UI elements through layouts (.xml) files.
And to use them in java class map them to their corresponding class.
And to do so we have to call method findViewById(int id); which returns the view of that perticuler element with given id.and thus we have to type cast it to respective component.
And thus if you have created a element already in xml why will you create a different object again at java end. so just map the element created with xml file.
2. crate UI elements through java end.
To use this feature use have to create the elements in java with new keywords ex. Button button = new Button(); and then set the all properties on that object.
But But But,
According to android philosophy you should create UI in xml, and write your core business logic in java end. And with this concept you can write neet and clean application code.
But it is only recommended not compulsory at all. now its up to you....
and i think at starting you feel it different but after some time you will start loving it...
Thats the beauty of android.
Thanks. i hope, i answered your question throughly.
Also, remember that Button is a subclass of View. The findViewById() method returns a generic View (any View or subclass of View that you put in a layout file). The cast to Button is saying "It's okay - I know this is a Button, not just a regular View," which allows you to access properties and methods of the Button that aren't available in the View superclass.
final Button callButton = (Button) findViewById(R.id.callButton);
I believe that when finding an XML view using findViewbyId(), it returns the view in the UI, but the returned view must be cast in order to be used as a button within the Java code, and have access to the button methods.
There are ways to create a button in the Java code without specifying it in the XML, but this practice differentiates the UI from the logic.
Plus, declaring UI elements in the XML is better because it is makes the process changing entire layouts easy through usage of of setContentView().
You have two options to create View component in android including Button
1- Define it in a layout XML file and access it using (Button) findViewById(R.id.button)
2- Create it dynamically in the code e.g. Button button = new Button();
both has their own advantages and disadvantages, for example, defining the UI in layout xml makes your Activity concise and and give you more flexibility by separating the UI from the actual code
Dynamic UI creation is useful in many applications that needs to create Views on-the-fly

How to write a app for Android in the same way as JFrame

I installed the ADT plugin for Android for Eclipse, and I don't like it.
I would like use my own Grid Layout the way I want and design windows by code (the same way as JFrame in Java, because I already know how to do this) not by click and drag.
How to do this in Android?
While I don't think it's a great idea to write the UI code in java, here's how you would do it.
First, you'll want to look at the android.view.* and the android.widget.* packages in the Android Reference docs.
Everything the the Xml corresponds to a View (or Subclass). So, if you see LinearLayout in the Xml, then there will be a LinearLayout java component as well.
So, in your Activity's onCreate() method, where normally you'd just set the content resource xml view, you can instantiate a Widget and set it directly.
public void onCreate(Bundle state) {
TextView tv = new TextView();
tv.setText("Hellow World);
setContentView(tv);
}
You might also need to the set the LayoutPararms as well, since most widgets need to know if they should wrap content or fill the parent.
Many of the Layout widgets are analogous to Swing Containers, ie, they accept children, so you can call addChild() with another view to create a widget hierarchy.
This should be enough to get you started.
As a final note, I'd like to reiterate that while you can build the complete UI in Java code, the Xml layout does offer some other benefits. For example the Xml layouts allow you to support multiple screen sizes, or different layouts (landscape vs portrait, etc), which is much harder to do (but not impossible) in Java. Also, you might be tempted to think that because the Views are in Xml, then they will be "slow" to be created on the device. But, Android optimizes the Xml resources, and in fact, I don't think they are even Xml at the time they are compiled into your App. So the resource Xml files are very efficient, and writing direct Java code for the Views probably won't get your much extra in terms of performance.

Group of Views (controls) on multiple screens

I am working on an Android project where a group of buttons needs to show on the bottom of every screen (activity) in the application. The group of buttons are basically a navigation bar. I want to know the best way to do this without creating new buttons for every activity. I have been around programming (C++/C#) for many years but am pretty new to Android and Java so if someone can point me in a general direction, it would be appreciated.
Thanks.
I bet you need to use "include" tag for xml layouts. It's the best when you need to reuse some UI components. See http://www.curious-creature.org/2009/02/25/android-layout-trick-2-include-to-reuse/ for the examples and description.
To elaborate on Konstantin's answer, after you've used include, you'll need to bind actions to these buttons.
If the buttons should have the same action regardless of the activity they are in, use the include tag to create their layout and then create a parent NavigationActivity (or whatever else you want to call it) class from which all your other activites will inherits.
In the parent NavigationActivity class' onCreate method, you can set up the onClickListener (and other needed stuff) for the buttons.

Categories

Resources