Hello I am trying to make a pop up window with 4 buttons that change the map type on a Google Maps activity. I have set the on click listener in the class with the GoogleMap object, but I get this error when clicking one of the buttons.
Process: com.student.nick.earthquakereport, PID: 7770
java.lang.IllegalStateException: Could not find method setMapNormal(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.widget.Button with id 'mapNormal'
at android.view.View$DeclaredOnClickListener.resolveMethod(View.java:4485)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4449)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21156)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
The dialog is launched in the same class the onClick methods are in.
layFlator = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
ViewGroup containter = (ViewGroup) layFlator.inflate(R.layout.map_settings, null);
mapSettings = new PopupWindow(containter, 750, 680, true);
mapSettings.setAnimationStyle(R.style.PopupAnimation);
mapSettings.showAtLocation(layout, Gravity.CENTER, 0,0);
containter.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mapSettings.dismiss();
return false;
}
});
The methods
public void setMapNormal(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mapSettings.dismiss();
}
public void setMapHybrid(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mapSettings.dismiss();
}
public void setMapTerrain(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
mapSettings.dismiss();
}
public void setMapSat(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
mapSettings.dismiss();
}
Thanks for taking a look
EDIT: The layout the popup opens
<?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:fadingEdge="horizontal|vertical"
android:fadingEdgeLength="4dp"
android:elevation="20dp"
android:background="#drawable/popwindow_border"
>
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Normal"
android:id="#+id/mapNormal"
android:layout_gravity="center_horizontal"
android:onClick="setMapNormal"/>
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Hybrid"
android:id="#+id/mapHybrid"
android:layout_gravity="center_horizontal"
android:onClick="setMapHybrid"/>
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Terrain"
android:id="#+id/mapTerrain"
android:layout_gravity="center_horizontal"
android:onClick="setMapTerrain"/>
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Satellite"
android:id="#+id/button2"
android:layout_gravity="center_horizontal"
android:onClick="setMapSat"/>
</LinearLayout>
.
So I looked around and found a tutorial, this is the proper way to do it.
layFlator = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View popUp = layFlator.inflate(R.layout.map_settings, null);
popupWindow = new PopupWindow(popUp, 750, 680, true);
popupWindow.setAnimationStyle(R.style.PopupAnimation);
Button btnHybrid = (Button) popUp.findViewById(R.id.mapHybrid);
btnHybrid.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
Log.d("hybrid", "called");
popupWindow.dismiss();
}
});
You are not set onClickListener correctly. Take a look at android:onClick.
For instance, if you specify android:onClick="sayHello", you must declare a public void sayHello(View v) method of your context (typically, your Activity).
Your error msg clearly says:
java.lang.IllegalStateException: Could not find method
setMapNormal(View) in a parent or ancestor Context for android:onClick
attribute defined on view class android.widget.Button with id
'mapNormal'
So, you are not accessing the method right in the onClickListener. You can't just call the method using
this.methodName()
inside a handler. You might want to use something like
ClassName.this.methodName()
or
getActivity().methodName()
Related
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"
I've been searching the error for about 2 hours on google , i can't figure out what it's wrong . It just force closes when I tap the button "butonCap", I didn't work with fragments until now
ERROR:
java.lang.IllegalStateException: Could not find method butonCap(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'cap'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:423)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:380)
at android.view.View.performClick(View.java:6897)
at android.widget.TextView.performClick(TextView.java:12693)
at android.view.View$PerformClick.run(View.java:26101)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Butoane.java - i just made another java file because i can't write any code in the fragment java file
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_fata);
final Button butonCap = (Button) findViewById(R.id.cap);
butonCap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent butonCap = new Intent(Butoanele.this, capul.class);
Butoanele.this.startActivity(butonCap);
}
});
}
}
fragment_fata.xml - this is just one of the 2 fragments from navigation view
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".FragmentFata"
android:background="#drawable/fata">
<!-- TODO: Update blank fragment layout -->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/cap"
android:layout_width="wrap_content"
android:layout_height="65dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:background="#drawable/button_outline"
android:paddingBottom="30dp"
android:onClick="butonCap"
android:text="Cap"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
You class should extends Fragment and inflate layout in onCreateView() callback.
Call getActivity().findViewById in onViewCreated() callback.
watch this guide
In fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fata, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
if (getView() == null) {
return;
}
final Button butonCap = (Button) getView().findViewById(R.id.cap);
butonCap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getView().getContext(), capul.class);
startActivity(intent);
}
});
}
I'm trying to inflate a simple PopupMenu for rename/delete options when a RecylerView item is longClicked. For some reason i'm getting an XML inflate error when I call mPopup.show() after loading my xml file into the inflater.
I use similar logic elsewhere in my app to make a PopupMenu and it works fine. I've even tried loading the working PopupMenu from an unrelated part of the app into this inflater and I see the same android.view.InflateException: Binary XML file line #17: Failed to resolve attribute at index 1 error in logcat, so maybe the XML file isn't the problem?
How can I get this PopupMenu to inflate and show itself?
Fatal Exception Logcat
05-31 23:02:27.421 19597-20019/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.foo, PID: 19597
android.view.InflateException: Binary XML file line #17: Failed to resolve attribute at index 1: TypedValue{t=0x2/d=0x7f01005d a=-1}
Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 1: TypedValue{t=0x2/d=0x7f01005d a=-1}
at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:761)
at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:7060)
at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:7241)
at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:438)
at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:370)
at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:369)
at android.view.LayoutInflater.inflate(LayoutInflater.java:505)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at android.support.v7.view.menu.MenuAdapter.getView(MenuAdapter.java:93)
at android.support.v7.view.menu.MenuPopup.measureIndividualMenuWidth(MenuPopup.java:160)
at android.support.v7.view.menu.StandardMenuPopup.tryShow(StandardMenuPopup.java:153)
at android.support.v7.view.menu.StandardMenuPopup.show(StandardMenuPopup.java:187)
at android.support.v7.view.menu.MenuPopupHelper.showPopup(MenuPopupHelper.java:290)
at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:175)
at android.support.v7.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:141)
at android.support.v7.widget.PopupMenu.show(PopupMenu.java:233)
at com.example.foo.FragmentChordMenu.showChordOptionsMenu(FragmentChordMenu.java:132)
at com.example.foo.CustomChordAdapter$ChordViewHolder$2.onLongClick(CustomChordAdapter.java:138)
at android.view.View.performLongClickInternal(View.java:5687)
at android.view.View.performLongClick(View.java:5645)
at android.view.View.performLongClick(View.java:5663)
at android.view.View$CheckForLongPress.run(View.java:22234)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
FragmentActivity
public class FragmentChordMenu extends Fragment implements CustomChordAdapter.onItemClickListener {
private static RecyclerView mCustomChordList;
private static CustomChordAdapter mRecyclerViewAdapter;
private static Context mContext;
private FloatingActionButton mFAB;
private View mPopupView;
private PopupWindow mCustomChordMenu;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRecyclerViewAdapter = new CustomChordAdapter(this);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
mContext = getActivity().getApplicationContext(); //stores application context for later use in fragment without risk
//of detachment
View v = inflater.inflate(R.layout.menu_fragment_chord, container, false);
LayoutInflater layoutInflater = (LayoutInflater)getActivity().getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
...
mFAB = (FloatingActionButton) v.findViewById(R.id.addChord);
mFAB.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mCustomChordMenu.showAtLocation(mPopupView, Gravity.CENTER, 10, 10);
mCustomChordList = (RecyclerView) mPopupView.findViewById(R.id.rv_userChords);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mCustomChordList.setLayoutManager(layoutManager);
mCustomChordList.setAdapter(mRecyclerViewAdapter);
}
});
return v;
}
public static void showChordOptionsMenu(final int position){
View anchorView = mCustomChordList.findViewHolderForAdapterPosition(position).itemView;
PopupMenu mPopup = new PopupMenu(mContext, anchorView);
mPopup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.delete:
mRecyclerViewAdapter.deleteChord(position);
return true;
case R.id.rename:
Log.d("FragmentChordMenu: ", "Rename clicked");
}
return true;
}
});
MenuInflater popupInflater = mPopup.getMenuInflater();
popupInflater.inflate(R.menu.popup_delete_chord, mPopup.getMenu());
mPopup.show(); //ERROR HERE
}
...
}
PopupMenu XML
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<item
android:id="#+id/rename"
android:title="#string/rename"/>
<item
android:id="#+id/delete"
android:title="#string/delete"/>
</menu>
FragmentActivity XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android.support.design="http://schemas.android.com/tools"
android:id="#+id/chordMenu"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/chordButtons"
android:orientation="vertical" >
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="16dp"
android:clickable="true"
app:fabSize="mini"
android:id="#+id/addChord"
app:borderWidth="0dp"
app:useCompatPadding="false"
android:src="#drawable/ic_add_black_24dp"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
The cause of the immediate issue here - the InflateException - was using the application Context for an appcompat-v7 PopupMenu.
mContext = getActivity().getApplicationContext();
...
PopupMenu mPopup = new PopupMenu(mContext, anchorView);
That Context won't have the correct theme resources set for a v7 widget, leading to the InflateException. The Activity does have the appropriate theme, though, and using that instead solves that particular issue.
mContext = getActivity();
After fixing that, however, a WindowManager$BadTokenException came up due to the PopupMenu being passed an anchor View from a PopupWindow. Popups must be anchored to a View in a top-level Window, and the Popup* classes are basically simple Views, thus the Exception.
A simple solution for this is to replace the PopupWindow with a Dialog, which does have a Window. For example:
AlertDialog dlg = new AlertDialog.Builder(getActivity()).setView(mPopupView).show();
Lastly, I would suggest that you modify your setup to remove the need for the static members in your Fragment class. Those static fields are likely to cause memory leaks, and your IDE may very well be warning you of that now. A listener interface similar to the one you have in CustomChordAdapter would suffice.
i have trouble to call layout programmatically, i try in xml using include and its work
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="#+id/btnTes"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/LL1"
android:orientation="vertical">
<include layout="#layout/extend">
</include>
<include layout="#layout/extend">
</include>
</LinearLayout>
but i want create it programmatically
this is my extend XML :
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView" />
<TextView
android:text="TextView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView2" />
and this is my java :
public class MainActivity extends AppCompatActivity {
Button btnTes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewGroup tes = (ViewGroup) findViewById(R.id.LL1);
btnTes = (Button) findViewById(R.id.btnTes);
final View extend = LayoutInflater.from(this).inflate(R.layout.extend,null);
btnTes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "KLIk", Toast.LENGTH_SHORT).show();
tes.addView(extend);
}
});
}
}
when i click btnTes
for the first clicked its ok, but when i click it again my program just force close. This is my error
FATAL EXCEPTION: main
Process: com.example.siwonhansamu.test, PID: 3796
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Thanks
You can't add the same view to multiple parents.
You have to do a copy of the view if you want it multiple times. You could do like this :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewGroup tes = (ViewGroup) findViewById(R.id.LL1);
btnTes = (Button) findViewById(R.id.btnTes);
btnTes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "KLIk", Toast.LENGTH_SHORT).show();
final View extend = LayoutInflater.from(view.getContext()).inflate(R.layout.extend, tes, false);
tes.addView(extend);
}
});
}
when i click btnTes for the first clicked its ok, but when i click it
again my program just force close.
that's the expected behavior. A View's instace can have only one parent. When you press the button for the second time extend has already a parent (tes), and you cannot call addView again on that instance. The quick fix is to move
final View extend = LayoutInflater.from(this).inflate(R.layout.extend,null);
into onClick. This way, every time you press on the Button, a new instance is created.
I'm new to this and I'm trying to follow some code from another answer. I have three text fields to enter the numbers that are used for the calculation and a button below that is supposed to change some text below it to the answer. There are no errors shown when I run the app but when I press the button the app crashes and I get error messages in the log. This is the code:
public class CalculatorActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
class NewActivity extends CalculatorActivity {
//Declare textviews as fields, so they can be accessed throughout the activity.
EditText editTextSubsPrevious;
EditText editTextSubsNow;
EditText editTextDays;
TextView calcText;
Button calcButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
//Bind the EditText views
editTextSubsPrevious = (EditText) findViewById(R.id.editTextSubsPrevious);
editTextSubsNow = (EditText) findViewById(R.id.editTextSubsNow);
editTextDays = (EditText) findViewById(R.id.editTextDays);
calcButton = (Button) findViewById(R.id.calcButton);{
View.OnClickListener onClickListener = new Button.OnClickListener() {
#Override
public void onClick(View v) {
//When the button is clicked, call the calculate method.
calculate();
}
};
}
}
public void calculate(){
//get entered texts from the edittexts,and convert to integers.
Double value1 = Double.parseDouble(editTextSubsPrevious.getText().toString());
Double value2 = Double.parseDouble(editTextSubsNow.getText().toString());
Double value3 = Double.parseDouble(editTextDays.getText().toString());
//do the calculation
Double difference = (value2 - value1) / 7;
Double percent = (difference / 325);
Double amount;
amount = value2 * Math.pow(1 + percent, value3);
calcText.setText(amount.toString());
}
}
}
}
Here is the error message:
FATAL EXCEPTION: main
Process: com.pausetheapp.futurefollowerandsubscribercalculator, PID: 3420
java.lang.IllegalStateException: Could not find method sendMessage(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'calcButton'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:325)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Here is the xml file:
<RelativeLayout 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.pausetheapp.futurefollowerandsubscribercalculator.CalculatorActivity"
tools:showIn="#layout/activity_calculator">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/textViewTitle"
android:id="#+id/textViewTitle"
android:textAlignment="center"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="#+id/editTextSubsPrevious"
android:layout_marginTop="28dp"
android:layout_below="#+id/textViewTitle"
android:layout_centerHorizontal="true"
android:hint="#string/previousSubsTextField"
android:width="300dp" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="#+id/editTextSubsNow"
android:layout_below="#+id/editTextSubsPrevious"
android:layout_centerHorizontal="true"
android:layout_marginTop="24dp"
android:width="300dp"
android:hint="#string/currentSubsTextField" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="#+id/editTextDays"
android:hint="#string/daysTextField"
android:width="300dp"
android:layout_marginTop="30dp"
android:layout_below="#+id/editTextSubsNow"
android:layout_alignLeft="#+id/editTextSubsNow"
android:layout_alignStart="#+id/editTextSubsNow" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="#string/accuracyText"
android:id="#+id/textViewAccuracy"
android:layout_below="#+id/editTextDays"
android:layout_alignLeft="#+id/editTextDays"
android:layout_alignStart="#+id/editTextDays"
android:textSize="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/calculateButton"
android:id="#+id/calcButton"
android:layout_marginTop="42dp"
android:layout_below="#+id/textViewAccuracy"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/calcDays"
android:id="#+id/calcText"
android:layout_marginTop="22dp"
android:textSize="25dp"
android:layout_below="#+id/calcButton"
android:layout_centerHorizontal="true"
android:gravity="center" />
I just added this line to the java file.
calcText = (TextView) findViewById(R.id.calcText);
There are two possibilites of error
1> You have not defined calcText
calcText.setText(amount.toString());
2> Or May be
Double value1 = Double.parseDouble(editTextSubsPrevious.getText().toString());
Double value2 = Double.parseDouble(editTextSubsNow.getText().toString());
Double value3 = Double.parseDouble(editTextDays.getText().toString());
editTextSubsPrevious,`editTextSubsNow`,`editTextDays` => does not contain numbers so that it can be parsed to `Doubles`
Probably, you have following attribute in your layout XML file:
android:onClick="sendMessage"
Then, when you click, android search for method sendMessage(View view) and it does not find (because you did not implemented)
Could not find method sendMessage(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'calcButton'
So, since your are setting a onClickListener at runtime, I think you can delete android:onClick="sendMessage" from layout file.
Also, line below should be fixed as follows:
calcButton = (Button) findViewById(R.id.calcButton);
calcButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//When the button is clicked, call the calculate method.
calculate();
}
});
In your layout most probably you have assigned sendMessage() method to handle onClick event and have not created any such method in activity.
check for android:onClick="sendMessage" in your layout.
Either create a method sendMessage(View view) and write your code there or remove it and use your calcBtn.setOnClickListner(View.OnClickListner Object).
If your app crashes in response to a button click it could be due to the following:
The function you registered for the onClick attribute of the button
in the layout .xml file does not exist in the activity. You can make sure the function name in the onClick attribute matches the function name you mean to call in your activity.
Something in the onClick function causes an Exception. If this is the case you can use the debugger by setting a breakpoint inside
that function and inspecting your code and values while you step
through the program. Debug Your App
if u r using this
calcButton = (Button) findViewById(R.id.calcButton);{
View.OnClickListener onClickListener = new Button.OnClickListener() {
#Override
public void onClick(View v) {
//When the button is clicked, call the calculate method.
calculate();
}
};
}
u should use
android:onClick="onClick"
else u need to use
calcButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//When the button is clicked, call the calculate method.
calculate();
}
});