Android Studio - image button is crashing after i click on it - java

I am trying to make some simple image click button to go to another activity but I can't get it to work.
It says:
Unfortunately, myapp has stopped.
If I highlighted my android: onClick="myButton" it says Method myButton' is missing in 'MainActivity' in my layout.xml
MainActivity.java
package com.zemoapps.alarmclockgold;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
//Old code "public class MainActivity extends AppCompatActivity {"
public class MainActivity extends AppCompatActivity {
private Button myButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView myTextview = (TextView) findViewById(R.id.RepeatingText);
TextView myTextview2 = (TextView) findViewById(R.id.CountDownText);
Typeface myCustomFont = Typeface.createFromAsset(getAssets(), "fonts/AndadaRegular.otf");
myTextview.setTypeface(myCustomFont);
myTextview2.setTypeface(myCustomFont);
}
public class MyCustomTextView extends TextView {
public MyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setTypeface(Typeface.createFromAsset(context.getAssets(),
"fonts/AndadaRegular.otf"));
}
}
public class AlarmPage extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (Button) findViewById(R.id.RepeatingImage);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, AddAlarm.class));
}
});
}
}}
Layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:andriod="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/BG"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#9e84d3"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.zemoapps.onething.MainActivity">
<ImageButton
android:id="#+id/RepeatingImage"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#00000000"
android:contentDescription="#null"
android:onClick="myButton"
android:scaleType="fitCenter"
android:src="#drawable/alarm1" />
</RelativeLayout>
AndroidManifest says there is error too:
java.lang.IllegalStateException: Could not find method myButton(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatImageButton with id 'RepeatingImage'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:307)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:266)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

Remove android:onClick="myButton" from ImageButton in your XML.
<ImageButton
android:id="#+id/RepeatingImage"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#00000000"
android:contentDescription="#null"
android:onClick="myButton" // remove this line from your xml
android:scaleType="fitCenter"
android:src="#drawable/alarm1" />

This is because you have extended AppCompatActivity.
It will work fine if you extend Activity.

You didn't define method for imagebutton click,you should add it to MainActivity like this:
public void myButton(View view){
}

Remove the next row from you ImageButton node:
android:onClick="myButton"
When you add it, Android will expect a method named "myButton" in your Activity.

Related

Accessing Parent Activity Button in Fragment Crashes App

Hey guys I am a beginner in Android Develpoment. I am currently learning Navigation Components, but stuck in this app. I am setting listener to the button present in the activity_main.xml inside the FirstFragment.java and SecondFragment.java but my app crashes. I don't know what I am doing wrong.
Main Activity.java
package com.ahstore.inventory;
import android.os.Bundle;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.ahstore.inventory.databinding.ActivityMainBinding;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration appBarConfiguration;
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
binding.fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:theme="#style/Theme.Inventory.AppBarOverlay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="#style/Theme.Inventory.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<HorizontalScrollView
android:id="#+id/horizontalScrollView"
android:layout_width="409dp"
android:layout_height="50dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:scrollIndicators="none"
android:scrollbarAlwaysDrawHorizontalTrack="false"
android:scrollbarAlwaysDrawVerticalTrack="false"
android:scrollbars="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
</HorizontalScrollView>
<fragment
android:id="#+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/horizontalScrollView"
app:navGraph="#navigation/nav_graph" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="#android:drawable/ic_input_add"
tools:ignore="SpeakableTextPresentCheck,SpeakableTextPresentCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
FirstFragment.java
package com.ahstore.inventory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.ahstore.inventory.databinding.FragmentFirstBinding;
public class FirstFragment extends Fragment {
private FragmentFirstBinding binding;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
View view=inflater.inflate(R.layout.fragment_first,container,false);
return view;
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button button1=view.findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
fragment_first.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="First" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
SecondFragment.java
package com.ahstore.inventory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.ahstore.inventory.databinding.FragmentSecondBinding;
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
View view=inflater.inflate(R.layout.fragment_second,container,false);
return view;
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button button=view.findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment);
}
});
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
fragment_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/cl"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<TextView
android:id="#+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="am second"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Error
2022-03-04 16:54:11.473 2392-2392/com.ahstore.inventory E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ahstore.inventory, PID: 2392
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ahstore.inventory/com.ahstore.inventory.MainActivity}: android.view.InflateException: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3800)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3976)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2315)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8550)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: android.view.InflateException: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Error inflating class fragment
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.ahstore.inventory.FirstFragment.onViewCreated(FirstFragment.java:35)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at com.ahstore.inventory.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:75)
at com.ahstore.inventory.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:69)
at com.ahstore.inventory.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:8198)
2022-03-04 16:54:11.474 2392-2392/com.ahstore.inventory E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8182)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3773)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3976)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2315)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8550)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Here are a few points that will help you understand your issue better
Your activity and fragments have their own respective layout files (xmls)
View are bound within their layout files. Simply put, if an element with id, say A, is present in activity_main.xml, then it can only be accessed when the layout being inflated is activity_main.xml. If the contentView of your Activity is activity_main.xml, it will be able to access all Views inside the layout file.
In fragments, the layout is inflated in the onCreateView method, which returns the resulting View for the Fragment. The findViewById(id) method is called against that View object. The method will look for the View with the given id inside that View only. If it is able to find the View it will return it, else it will return null. Same goes for finding a View inside an Activity (you do not need to specify the View for an Activity as it will automatically reference the layout that is specified in setContentView).
Now that we have the above points cleared, we can see the issue that you are facing. Firstly, the buttons with ids button1 and button2 are in your activity_main.xml layout file. However you are trying to access these from your Fragment1 and Fragment2 classes. But your Fragment1 and Fragment2 classes have their own layout files which do not have the two buttons. So, when you try to retrieve the buttons (using findViewById), it returns null because the buttons are not present in the layout. You then try to set a click listener. Since, the button object is null, calling any method on it will result in a Null Pointer Exception being throw.
We now understand what you are doing wrong. Now, how do we fix this. First you need to understand what it is you want to achieve. In this case I would suggest that you move both buttons to the respective Fragment layouts i.e. the View with id button1 will go to Fragment1 and the View with id button2 will go to Fragment2. This should help resolve the NPE that you are facing.
Still there are some cases where a Fragment might want to access a View that is present in its parent Activity. One of the ways to do this would be to
Create a public method in your Activity class which returns a View with the given id.
public View getViewById(int id) {
return findViewById(id);
}
Use this method in your Fragment by doing so
((MainActivity) getActivity()).getViewById(R.id.button1)
Other approaches involve using Interfaces which I am sure you will learn about as you continue learning more.
Just to wrap things up, you have two ways to go about fixing your issue. Either move the buttons to the fragment layout files or create a public method to retrieve those views.

What is the correct use of an onClick method in fragments to open new activities?

Re-Edit: For those interested the method for onClick was resolved below. Turns out you cannot create separate classes for controls so the button controls need to be inside the current active class.
The issue: In my fragment I have included several controls, one of which is a button that should open a new activity. When clicking the button I get the following crash...
This is the LogCat error when clicking the button in my current active Fragment
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.paymentdemo, PID: 14352
java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'button_next_trans'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:424)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:381)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
This is the fragment hosting the controls
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/transaction_header"
style="?textGroupheader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="20dp"
android:text="#string/group_header"
android:textStyle="bold" />
<!-- Spinner displays accounts available using SpinnerActivity -->
<include
layout="#layout/fragment_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Radio checks on or off. Still need to link selected as fragments for button on click behaviour -->
<include
layout="#layout/fragment_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Button will take selected radio and open related activity, for now we just go to MainActivity -->
<include
layout="#layout/fragment_button"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The button control code
<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"
tools:context=".ButtonActivity">
<Button
android:id="#+id/button_next_trans"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:background="#drawable/action_button"
android:paddingStart="24dp"
android:paddingLeft="24dp"
android:paddingTop="8dp"
android:paddingEnd="24dp"
android:paddingRight="24dp"
android:paddingBottom="8dp"
android:text="#string/next"
android:textColor="#color/colorWhite"
android:onClick="goToPayments"/>
</FrameLayout>
The button activity
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class ButtonActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_button);
}
public void goToPayments(View view) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
}
I'm not experienced so my implementation may be a bit rusty. If you have any advice on how to properly implement a button onClick method I would be grateful.
You need to declare the button and View for framgment
Like this
Button button;
public View myView;
Then in onCreate initialize like this
myView = inflater.inflate(R.layout.fragment_button,container,false);
button = (Button) myView.findViewById(R.id.button_next_trans);
then create method like this this,
public void payments(){
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(),MainActivity.class)
startActivity(i);
}
}
}
And at end of onCreate() method return view.
return myView;
And call payments(); in onCreate
public class ButtonActivity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_button);
Button btnPay = (Button)findViewById(R.id.button_next_trans);
btnPay.setOnClickListener(this);
}
public void goToPayments(View view) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
#Override
public void onClick(View v) {
{
switch (v.getId()) {
case R.id.button_next_trans:
goToPayments();
break;
}
}
}}
Remove below line from xml
android:onClick="goToPayments"

Logcat error when switching activity causes app to crash after pressing a button

I created an app with 2 activities but when i press the button to enter the second activity the app crashes. I looked at many questions over here and searched the problem on Google but i didnt find any solution. I looked at the Logcat and it says it creates a null exception but I dont know why and where that happens.
MainActivity java code
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText marius;
final Button maria;
final TextView magdalena;
marius = findViewById(R.id.cascarabete);
maria = findViewById(R.id.necarbogazificat);
magdalena = findViewById(R.id.sternocleidomastoidian);
maria.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), activity2.class);
startActivity(i);
}
});
}
}
MainActivity Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/necarbogazificat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="34dp"
android:text="#string/push"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/cascarabete" />
<EditText
android:id="#+id/cascarabete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/sternocleidomastoidian"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="45dp"
app:layout_constraintStart_toStartOf="#+id/necarbogazificat"
app:layout_constraintTop_toBottomOf="#+id/necarbogazificat" />
</android.support.constraint.ConstraintLayout>
Second Activity java code
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class activity2 extends Activity {
TextView intrebare = findViewById(R.id.intrebare);
EditText raspuns = findViewById(R.id.raspuns);
Button buton = findViewById(R.id.button);
TextView rasplata = findViewById(R.id.rasplata);
String s;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
}
}
Also, this is what the logcat says (red color script):
09-19 20:56:31.237 20504-20504/com.example.iulian.ffgerg E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.iulian.ffgerg, PID: 20504
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.iulian.ffgerg/com.example.iulian.ffgerg.activity2}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2639)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2812)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6311)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
at android.app.Activity.findViewById(Activity.java:2380)
at com.example.iulian.ffgerg.activity2.<init>(activity2.java:11)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2629)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2812) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6311) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762) 
You must call findViewById in onCreate, rather than when you initialize your fields. (When the Activity instance is instantiated, there's no associated Window/view hierarchy yet, which causes the crash you see.)
Suggested alternative second activity code:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class activity2 extends Activity {
TextView intrebare;
EditText raspuns;
Button buton;
TextView rasplata;
String s;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
intrebare = findViewById(R.id.intrebare);
raspuns = findViewById(R.id.raspuns);
buton = findViewById(R.id.button);
rasplata = findViewById(R.id.rasplata);
}
}

android fragments problems

i wrote a toDO list for my android class. It totally works , but now i want to display the todo list on a fragment ( so it can be its on tab). but when i tried making the fragment , i get a weird error when i try to run it. apparently the error comes from my main activity . so the way i have it set up is that, my main activity has a button that opens the fragment that has all the TOdolist stuff in it. but when i run it on my phone i get a unfortunately TodoList ha stopped as soon as it runs. the error is get is
06-10 22:21:51.284 5302-5302/com.example.mike.todolist D/AbsListView﹕ Get MotionRecognitionManager
06-10 22:21:51.304 5302-5302/com.example.mike.todolist D/AndroidRuntime﹕ Shutting down VM
06-10 22:21:51.304 5302-5302/com.example.mike.todolist W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x417c2898)
06-10 22:21:51.314 5302-5302/com.example.mike.todolist E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.mike.todolist.ToDoFragment.onCreateView(ToDoFragment.java:38)
at android.app.Fragment.performCreateView(Fragment.java:1699)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075)
at android.app.BackStackRecord.run(BackStackRecord.java:682)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1455)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5455)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
at dalvik.system.NativeStart.main(Native Method)
my main activity look like
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.view.View;
public class MainActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.todo_main_activity);
super.onCreate(savedInstanceState);
Button button1 = (Button) findViewById(R.id.fragButton);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction
=fragmentTransaction=fragmentManager.beginTransaction();
ToDoFragment fragment = new ToDoFragment();
fragmentTransaction.add(R.id.mainLL, fragment);
fragmentTransaction.commit();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return true;
}
}
My main activity xml is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="#+id/mainLL"
android:layout_height="fill_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="frag"
android:id="#+id/fragButton"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:onClick="fragButtonClick"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Fragment.java
package com.example.mike.todolist;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import com.example.mike.todolist.db.Contract;
import com.example.mike.todolist.db.DBHelper;
/**
* Created by mike on 6/10/15.
*/
public class ToDoFragment extends ListFragment {
public ListAdapter listAdapter;
public DBHelper helper;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view=inflater.inflate(R.layout.fragmentlayout, container, false);
// Inflate the layout for this fragment
update();
Button doneButton = (Button)view.findViewById(R.id.doneButton);
doneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
View v = (View) view.getParent();
TextView taskTextView = (TextView) v.findViewById(R.id.taskTextView);
String task = taskTextView.getText().toString();
String sql = String.format("DELETE FROM %s WHERE %s = '%s'",
Contract.TABLE_NAME,
Contract.Columns.TASK,
task);
helper = new DBHelper(getActivity());
SQLiteDatabase sqlDB = helper.getWritableDatabase();
sqlDB.execSQL(sql);
update();
}
});
Button addButton = (Button)view.findViewById(R.id.AddButton);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
switch (R.id.add_task) {
case R.id.add_task:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Add a task");
builder.setMessage("What would you like to do?");
final EditText input = new EditText(getActivity());
builder.setView(input);
builder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String task = input.getText().toString();
helper = new DBHelper(getActivity());
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.clear();
cv.put(Contract.Columns.TASK, task);
db.insertWithOnConflict(Contract.TABLE_NAME, null, cv, SQLiteDatabase.CONFLICT_IGNORE);
update();
}
});
builder.setNegativeButton("Cancel", null);
builder.create().show();
}
}
});
return view;
}
private void update() {
helper = new DBHelper(getActivity());
SQLiteDatabase sqlDB = helper.getReadableDatabase();
Cursor cursor = sqlDB.query(Contract.TABLE_NAME,
new String[]{Contract.Columns._ID, Contract.Columns.TASK},
null, null, null, null, null);
listAdapter = new SimpleCursorAdapter(
getActivity(),
R.layout.task_view,
cursor,
new String[]{Contract.Columns.TASK},
new int[]{R.id.taskTextView},
0
);
this.setListAdapter(listAdapter);
}
}
and this is my fragmentlayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="#+id/mainLL"
android:layout_height="fill_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="#color/grey"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Task"
android:id="#+id/AddButton"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:onClick="AddButtonClick"
android:layout_gravity="center_horizontal" />
</LinearLayout>
taskview
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/taskTextView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="20dp"
android:textColor="#color/black"
android:typeface="sans"
android:layout_toLeftOf="#+id/doneButton"
android:layout_alignBottom="#+id/doneButton"
android:gravity="center_vertical"
android:textStyle="bold"
android:layout_alignTop="#+id/doneButton" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Done"
android:id="#+id/doneButton"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:onClick="DoneButtonClick"
/>
</RelativeLayout>
According to android developers official website (HERE)
ListActivity has a default layout that consists of a single, full-screen list in the center of the screen. However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain a ListView object with the id "#android:id/list" (or list if it's in code)
for example:
<?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"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
</LinearLayout>
So either add a listview to your list activity xml or if you don't need a list view in your activity then simply use FragmentActivity to hold fragments.There is no point in using ListActivity unless it holds a ListView.
Your class is extending to a ListActivity which requires the ListView element in the xml. Your purpose be best served by extending your MainActivity class to Activity and fragments (if any) to Fragments class....
Add an list view to your xml with id android.R.id.list
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
add this xml to your layout
use Activity or FragmentActivity instead of ListActivity
if you want to use ListActivity see here once. you can use ListActivity without setting content view (setContentView()). you can directly setAdapter. or else use your own layout having one ListView with id as "#android:id/list"
EDIT :
public void onClick(View arg0) {
TextView taskTextView = (TextView) view.findViewById(R.id.taskTextView);//directly use 'view' if 'R.id.taskTextView'it present in 'view'
String task = taskTextView.getText().toString();
String sql = String.format("DELETE FROM %s WHERE %s = '%s'",
Contract.TABLE_NAME,
Contract.Columns.TASK,
task);
helper = new DBHelper(getActivity());
SQLiteDatabase sqlDB = helper.getWritableDatabase();
sqlDB.execSQL(sql);
update();
}

Can I use setContentView outside the oncreate method?

I have seen many people telling that you can set setContentView outside the oncreate method, but I didn't find anywhere an example. Now when I try to use setContentView, my app just crashes. Here is my source code:
AlarmActivity.java:
package com.alarm.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.RelativeLayout;
public class AlarmActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button buton = new Button(this);
buton.setId(101);
buton.setText("New alarm");
buton.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
RelativeLayout layout1 = new RelativeLayout(this);
layout1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout1.addView(buton);
setContentView(layout1);
Button nou =(Button)findViewById(101);
nou.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
New_ala nou1=new New_ala();
nou1.nou_alarma();
}
});
}
}
New_ala.java:
package com.alarm.example;
public class New_ala extends AlarmActivity{
public void nou_alarma() {
setContentView(R.layout.timepicker);
}
}
TimePicker.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TimePicker
android:id="#+id/timePicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true">
<Button
android:id="#+id/picker_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Save">
</Button>
<Button
android:id="#+id/picker_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel">
</Button>
</LinearLayout>
</LinearLayout>
On more detail, I can use setContentView(R.layout.timepicker) inside the oncreate method without any problems so the problem is that setContentView isn't working properly inside the New_ala.java class. Can anyone help me?
The code after setting the intent:
AlarmActivity:
package com.alarm.example;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class AlarmActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivity(new Intent(this, NewAlarmActivity.class));
}
}
NewAlarmActivity:
package com.alarm.example;
import android.os.Bundle;
public class NewAlarmActivity extends AlarmActivity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timepicker);
}
}
You can call setContentView any time you are running on the event (UI) thread. Be aware that when you do, any fields you initialized by calling findViewById will need to be reset.
The best way to do that is to have multiple activities: instead of nou1.nou_alarma();, create an intent and start a new activity with the new layout.
startActivity(new Intent(this, NewAlarmActivity.class));
And in the onCreate method of NewAlarmActivity, set the content view to R.layout.timepicker
The setContentView() method can be called only once per activity. If you want to completely change the layout at some point you should either go for ViewFlipper or have 2 layouts in the activity and show only one of them at given time by calling view.setVisibility(View.GONE); and view.setVisibility(View.VISIBLE); respectively.

Categories