I have written UI functions in the MainActivity.java (shown below). Now, due to design issues, my requirement is to separate these functions from MainActivity.java and write into other file and, then these functions will interact with UI elements. How can I separate UI functions from MainActivity.java.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
// There is "Off" button On UI. Onclick event of the button, this function
// is called.
public void OffCommandInterface(View view) {
}
// There is "SetTemp" button On UI. Onclick event of the button,
//this function reads data from textbox and send data to other module.
public void SetTempCommandInterface(View view) {
}
// There is "SetTemp" button On UI. Onclick event of the button,
//this function reads data from textbox and send data to other module.
public void profileRequestInterface(View view){
}
}
I am attaching activity_main.xml file for the reference.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:onClick="profileRequestInterface"
android:text="#string/button_send" />
</LinearLayout>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Switch Off Heater"
android:onClick="OffCommandInterface" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/edit_temp"
android:layout_width="136dp"
android:layout_height="wrap_content" >
</EditText>
<Button
android:id="#+id/temp"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:onClick="SetTempCommandInterface"
android:text="SetTemp" />
</LinearLayout>
</LinearLayout>
As you declared your Button's onClick as part of layout xml its hard to separate out from Activity class scope.
When you declare your view's onClick as layout xml, it will attached with the Activity who called setContentView() on that layout. So you have to define your all Button's click method in Activity itself.
Now If you want to separate out this logic as design pattern issue, than remove onClick from xml layout file, create custom onClick listener as different java class and override onClick in that class, define your button's in onCreate() of Activity and set custom onClick listener to those buttons.
Example: (This is the just example, you can change with your code and use case)
public class CustomOnClickListener implements View.OnClickListener{
private Context appContext;
public CustomOnClickListener(Context context)
{
appContext = context;
}
#Override
public void onClick(View arg0) {
switch(arg0.getId())
{
case R.id.button1:
// There is "Off" button On UI. Onclick event of the button, this function
// is called.
break;
}
}
}
Now, in your Activity,
public class MainActivity extends Activity {
Button buttonOff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonOff = (Button)findViewById(R.id.button1);
buttonOff.setOnClickListener(new CustomOnClickListener(this));
}
You can start by removing android:onClick from your XML and handling it in the code. I never understood this practice other than for learning purposes. This should get you started.
public class MainActivity extends Activity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
this.OffCommandInterface();
break;
default:
break;
}
private void OffCommandInterface() { }
private void SetTempCommandInterface() { }
private void profileRequestInterface() { }
}
Related
When I click on the Sign up txt on my application it crashes I've tried almost everything i could find including the XML onClick
XML clickable
onClick
public class LoginActivity extends AppCompatActivity
{
TextView sign_up_text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
sign_up_text = (TextView) findViewById(R.id.sign_up);
sign_up_text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(LoginActivity.this, RegisterActivity.class));
}
});
}
}
xml:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/sign_up_text"
android:textSize="18dp"
android:gravity="center"
android:layout_alignParentBottom="true"
android:id="#+id/sign_up"
android:clickable="true"
android:onClick="onClick"
/>
Android app crashes with no failure
You have android:onClick="onClick" attribute in your xml. And you have also define sign_up_text.setOnClickListener in java.
You can do only one thing at a time.
1.
If you want to use sign_up_text.setOnClickListener , you simply need to remove android:onClick="onClick" from xml file.(Reference)
2.
If you want to use android:onClick="onClick", you should define new method in your activity like:(Reference)
public void onClick(View view) {
}
First solution is to remove android:onClick="onClick" from your XML, according to my perception the reason of crash is the function name called on onClick of your button click define in XML is "onClick" which is also override function of setOnClickListner
#Override
public void onClick(View v){
//todo your code
}
Second Solution is if you use onClick in XMl change function name other that override function onClick like:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/sign_up_text"
android:textSize="18dp"
android:gravity="center"
android:layout_alignParentBottom="true"
android:id="#+id/sign_up"
android:clickable="true"
android:onClick="myFunction"
/>
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
private myFunction(View view){
}
I've been dealing with this problem for awhile and have looked at all the relevant questions I could find, such as: this one, this one, and this one. Could you help me correct this error? It's the only one being thrown by the logcat.
java.lang.IllegalStateException: Could not find method playPauseMusic(View) in a parent or
ancestor Context for android:onClick attribute defined on view class
android.support.v7.widget.AppCompatImageButton with id 'playPause'
Relevant code:
radio.java
package com.example.jacob.wutk;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import java.io.IOException;
public class radio extends AppCompatActivity {
/** Called when the user touches the button */
public void playPauseMusic (View view, final ImageButton playPause) throws IOException {
String url = "http://streamer.cci.utk.edu:8000/wutk-vorbis"; // your URL here
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer){
mediaPlayer.start();
}
});
playPause.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
playPause.setImageResource(R.drawable.play1);
} else {
playPause.setImageResource(R.drawable.pause1);
}
}
});
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepareAsync();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
}
}
activity_radio.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
tools:context="com.example.jacob.wutk.radio">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left|center_vertical"
android:scaleType="centerCrop"
android:src="#drawable/background_mic1"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="1.0dip"
android:paddingLeft="4.0dip"
android:paddingRight="4.0dip"
android:paddingTop="5.0dip">
<ImageButton
android:id="#+id/playPause"
android:layout_width="0.0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:background="?android:selectableItemBackground"
android:clickable="true"
android:onClick="playPauseMusic"
android:scaleType="fitCenter"
android:src="#drawable/play1"/>
<ImageView
android:layout_width="0.0dip"
android:layout_height="fill_parent"
android:layout_marginRight="5dp"
android:layout_weight="1.0"
android:background="?android:selectableItemBackground"
android:scaleType="fitCenter"
android:src="#drawable/logo"/>
</LinearLayout>
</FrameLayout>
Defining onClick in xml means you need to define it for a particular view here is ImageButton you can not have two arguments in that method.
Your error is also saying that Could not find method playPauseMusic(View) means compiler needs a public method with single parameter View, whereas you were having two parameters: View & ImageButton.
This is the reason why you where getting that error. Just remove one argument from the method and it will work.
Do it like this :
public class radio extends AppCompatActivity {
/** Called when the user touches the button */
public void playPauseMusic (View playPause) {
String url = "http://streamer.cci.utk.edu:8000/wutk-vorbis"; // your URL here
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer){
mediaPlayer.start();
}
});
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
((ImageButton)playPause).setImageResource(R.drawable.play1);
} else {
((ImageButton)playPause).setImageResource(R.drawable.pause1);
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepareAsync();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
}
}
One more thing writing android:onClick="playPauseMusic" means the method playPauseMusic will be called on Button click so you have already defined a button click so no need to define it inside the method by playPause.setOnClickListener so I have removed that code.
Your code possibly should start with:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
}
You're specifying onClick in xml
android:onClick="playPauseMusic"
So, the method works, you've got inner onClicks too. If they are some views.
You gotta initialize and get it from the xml in code, for ex-
If you have ImageButton in xml, whose id is "playPause"
ImageButton playPause; //Declare it here if you wanna use it in all other places in the class or outside of your class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
playPause = (ImageButton)findViewById(R.id.playPause);
playPause.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
//OnCLick Stuff
}
});
}
In Your case, you've got onClick attribute in xml and another onCLick in code. You Use one.
The question is already answered but I hope this will help someone like me in the future. I was having this error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test1, PID: 6892
java.lang.IllegalStateException: Could not find method btnClickStartThread(View) in a parent or ancestor Context for android:onClick attribute defined on view class com.google.android.material.button.MaterialButton with id 'btnStartThread1'
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:447)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:405)
After struggling a lot I got it fixed by going to layouts and I realized I had two layouts:
activity_main.xml
activity_main.xml (v21)
My changes were just reflecting on one and the app was loading other version of layout.
As suggested here
Android Studio not deploying changes to app
Hello I want that my methods work instantly when the user enters the application.
For now I have an onClick event in my xml which activates so to say my methods(this works).
the xml:
<TextView
android:id="#+id/cd_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:paddingBottom="0dp"
android:text="time"
android:textColor="#000"
android:textSize="21sp"
android:onClick="dateEnd"/>
and Main Activity.java
String dateStopKukuk = "21 Dec 2015";
private void displayDateEnd(String etime) {
TextView priceTextView = (TextView) findViewById(R.id.cd_start);
priceTextView.setText(etime);
}
public void dateEnd(View v) {
displayDateEnd(dateStopKukuk);
}
Edit: I added a comments to explain you this code.
Try this:
import android.app.Activity;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener
{
// onClick method is called when one of view is clicked. (you must use setOnClickListener on this View to inform system to call this)
#Override
public void onClick(View v)
{
// check if clicked view is cd_start
if(v.getId() == R.id.cd_start)
{
// true cd_start is clicked
displayDateEnd(dateStopKukuk);
}
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); // REQUIRED!!! When you don't add this your app will be crash.
setContentView(R.layout.activity_main); // sets activity_main as layout (if you use different name of layout replace activity_name with your layout name)
findViewById(R.id.cd_start).setOnClickListener(this); // finds view with cd_start id and sets click listener. When this view is clicked system calls onClick method.
// and now your code what do you want to do when activity is creating.
}
String dateStopKukuk = "21 Dec 2015";
private void displayDateEnd(String etime) {
TextView priceTextView = (TextView) findViewById(R.id.cd_start);
priceTextView.setText(etime);
}
/* You don't need dateEnd method now */
}
XML:
<TextView
android:id="#+id/cd_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:paddingBottom="0dp"
android:text="time"
android:textColor="#000"
android:textSize="21sp"
/> <!-- You don't need android:onClick -->
In your activity.
I hope it helped you.
I created a normal button in main.XML and in Java I added added a Toast message when clicking it. My problem is I need to hide it when clicked, but that involves R.id.main or something like that. The problem is I get the error "Unknown entity 'id'". Am I missing imports?
Imports:
package com.redstonelamp.DroidRedstoneLamp;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
import android.view.View. *;
Code:
public class MainActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void confirmClicked(View view){
Toast.makeText(getApplicationContext(), "Please choose a version to download",
Toast.LENGTH_LONG).show();
}
}
If you want to hide your button you have two possibilities :
1. With a Listener
Let's say you have this XML file :
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
In your main class you will need to retrieve your Button and subscribe your MainActivity to the click event of this button.
MainActivity
public class MainActivity extends Activity implements View.onClickListener
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// this will inflate all the UI elements you have added
// in your main.xml file
setContentView(R.layout.main);
// here you retrieve the button in the layout by its ID
Button myButton = findViewById(R.id.my_button);
// here you tell your button he should propagate the
// Click event to this Activity.
myButton.setOnClickListener(this);
}
#Override
public void onClick(View view)
{
// here you handle the click
// the view parameter is the view that was clicked
// therefore your button :)
// so all you have to do is to set it's visibility
view.setVisibility(View.INVISIBLE);
}
}
2. Directly by naming the method
The mechanism behind is the same but this one allows you to have a custom method name. To do this you will have to add a field in the XML file named : onClick.
This field will contain the name of the method that will handle the click.
This method has to be implemented in the Activity / Fragment in which you have inflated this Button (with the setContentView method).
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="myOnClickMethod" />
</LinearLayout>
Then in your MainActivity :
MainActivity
public class MainActivity extends Activity implements View.onClickListener
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// this will inflate all the UI elements you have added
// in your main.xml file
setContentView(R.layout.main);
}
public void myOnClickMethod(View view)
{
// here you handle the click
// the view parameter is the view that was clicked
// therefore your button :)
// so all you have to do is to set it's visibility
view.setVisibility(View.INVISIBLE);
}
}
Hope this will help you.
Cheers
I'm attempting to change a TextView between two activities. The problem is, when I change the text in the other activity from main activity, it works fine, the screen goes to the other activity and the text has been changed. However I have another button which takes me to the other activity from Main, but the newly updated text has disappeared when I press it. Any help?
MyActivity.java
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final EditText et = (EditText) findViewById(R.id.editText1);
Button b = (Button) findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MyActivity.this, Second.class);
intent.putExtra("thetext", et.getText().toString());
startActivity(intent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onClickGoToActivity(View view) {
setContentView(R.layout.second);
}
}
Second.java
public class Second extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(getIntent().getExtras().getString("thetext"));
}
}
activity_my.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MyActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/editText1"
android:layout_centerHorizontal="true"
android:hint="Change me"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button1"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Add text in other activity"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/go_to_activity_button"
android:text="Go to activity"
android:layout_centerHorizontal="true"
android:layout_marginTop="200dp"
android:onClick="onClickGoToActivity"/>
</RelativeLayout>
second.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:textSize="30sp"/>
</LinearLayout>
AndroidManifest.xml
Second class activity:
I presume the problem lies here:
public void onClickGoToActivity(View view) {
setContentView(R.layout.second);
}
where the newly changed TextView is being reset back to the original layout (where the TextView is empty with no text). I'm not sure how to fix this as I'm new to Android.
Thank you.
changing content view of activity is a bad idea to start another activity. Simply you just do the same thing which is
public void onClickGoToActivity(View view) {
Intent intent = new Intent(MyActivity.this, Second.class);
intent.putExtra("thetext", et.getText().toString());
startActivity(intent);
}