Android app crashing on method call from menu item - java

I have a function called createGrid that crates a grid of buttons in a Gridlayout (code below), sets their listener and adds a custom layout called no_padding_button to each one.
after creating the grid, depending on what button(s) the user has clicked on I have another function called saveDesign that iterates through the gridlayout and returns the number of clicked buttons depending on their tag. I call saveDesign from a menu Item.
The problem is that as soon as I called the saveDesign method, the app crashes.
The grid works fine, you click buttons, they change color and their tag changes but some reason trying to read through the gridlayout crashes the app.
can you guys help me understand what the error in my code is?
Thanks
//method to create a new grid, the number of rows and columns come from the dialogue inside the activity and then passed to this function
void createGrid(final Context context, GridLayout gridLayout) {
gridLayout.setColumnCount(totalColumns); //set the number of rows of the gridlayout
gridLayout.setRowCount(totalRows); //set the number of columns of the grid layout
//add the buttons and implement their listeners
for (int i = 0; i < totalRows; i++) {
for (int j = 0; j < totalColumns; j++) {
Button button = new Button(context);
//no padding
button.setBackground(context.getResources().getDrawable(R.drawable.no_padding_button));
//set the name of the button according to its position
button.setText(Integer.toString(i) + "," + Integer.toString(j)+",");
//hide the name, the user does not need to see this information at this moment
button.setTextColor(View.INVISIBLE);
//setting up the layout parameters for each button
GridLayout.LayoutParams param = new GridLayout.LayoutParams();
param.setMargins(0, 0, 0, 0);
button.setLayoutParams(param);
//button listener
button.setOnClickListener(new View.OnClickListener() {
boolean already_clicked = false;
#Override
public void onClick(View v) {
//on click, hide the button
Button button = (Button) v;
if(!already_clicked){
//change the color of the selected buttons as an indication
button.setBackgroundColor(context.getResources().getColor(R.color.selected_button));
button.setTag(1);
already_clicked =true;
}
else{
button.setBackgroundColor(context.getResources().getColor(R.color.unselected_button));
button.setTag(0);
already_clicked =false;
}
}
});
gridLayout.addView(button);
}
}
Toast.makeText(context, "Grid Created", Toast.LENGTH_SHORT).show();
}
saveDesing method:
public void saveDesign(){
int temp=0;
for (int i=0;i<gridLayout.getChildCount(); i++){
Button childButton = (Button)gridLayout.getChildAt(i);
if(childButton.getTag().toString() == "1"){
temp++;
}
}
Toast.makeText(this, Integer.toString(temp), Toast.LENGTH_SHORT).show();
}
the xml code of the activity holding the gridlayout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<HorizontalScrollView android:id="#+id/HorizontalScrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
</GridLayout>
</HorizontalScrollView>
</ScrollView>
UPDATE 1 the error log , i also tried string.equals("1") but i got the same error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test.gridtest, PID: 3247
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Object.equals(java.lang.Object)' on a null object reference
at com.example.abtin.gridtest.MainActivity.saveDesign(MainActivity.java:85)
at com.example.abtin.gridtest.MainActivity.onOptionsItemSelected(MainActivity.java:109)
at android.app.Activity.onMenuItemSelected(Activity.java:3204)
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:406)
at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:103)
at android.support.v7.app.AppCompatDelegateImplV9.onMenuItemSelected(AppCompatDelegateImplV9.java:667)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:810)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:957)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:947)
at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:616)
at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:153)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22260)
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)

If you don't click on button, it haven't tag. Therefore childButton.getTag() return null and toString crash your app.
So check in saveDesign()
if(childButton.getTag() != null) {
if(childButton.getTag().toString() == "1"){
temp++;
}
}
or set button tag when create button.

Related

Add views to linear layout in a different activity (popup activity) Android Studio (Java)

I have a popup activity that I create in my program that contains a scrollable view with a linear layout.
<ScrollView
android:id="#+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toTopOf="#+id/averageRollsText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/totalRollsText">
<LinearLayout
android:id="#+id/histogramLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginTop="2dp"
android:orientation="vertical" />
</ScrollView>
I want to populate that scrollable view with TextView objects, but I am unable to correctly interact with the linear layout,
as it returns null when trying to get the view by Id
I have already done the same thing earlier but within the same view, so I am fairly certain my code is correct to add them, it's just due to the interaction between different activities that is causing the issue. Any help would be appreciated.
public void generateHistogramButton(View view){
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
final View histogramPopupView = getLayoutInflater().inflate(R.layout.histogram_popup, null);
TextView totalRollsText = histogramPopupView.findViewById(R.id.totalRollsText);
TextView avgText = histogramPopupView.findViewById(R.id.averageRollsText);
TextView minText = histogramPopupView.findViewById(R.id.minRollText);
TextView maxText = histogramPopupView.findViewById(R.id.maxRollText);
totalRollsText.setText("Total Rolls: " + gameHistogram.getTotalRolls());
avgText.setText("Avg: " + gameHistogram.getAverageRoll());
minText.setText("Min: " + gameHistogram.getMinRoll());
maxText.setText("Max: " + gameHistogram.getMaxRoll());
View histogramLinearLayout = histogramPopupView.findViewById(R.id.histogramLinearLayout);
int[] totalRolls = gameHistogram.returnRolls();
int[] histogramValues = gameHistogram.generateHistogram(20);
String histogramString = "";
for(int i = 0; i < gameHistogram.getNumRange(); i++){
TextView newHistText = new TextView(histogramPopupView.getContext());
newHistText.setSingleLine(true);
newHistText.setId(100+i);
newHistText.setText("");
newHistText.setTextSize(22);
newHistText.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
histogramString = "";
histogramString += (String.format("%2d ",i+gameDice.getMinRoll()) + ": (" + String.format("%2d",totalRolls[i]) + ") ");
for(int j = 0; j <= histogramValues[i]; j++){
histogramString += "#";
}
histogramString += "\n";
newHistText.setText(histogramString);
((LinearLayout) histogramLinearLayout).addView(newHistText);
}
Button exitHistogramButton = histogramPopupView.findViewById(R.id.closeHistogramButton);
dialogBuilder.setView(histogramPopupView);
Dialog dialog = dialogBuilder.create();
dialog.show();
exitHistogramButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
dialog.dismiss();
}
});
}
You don't access the views of one activity from another, ever. You can't even rely on the other Activity still existing, the OS may have deleted it as soon as the 2nd activity started. Instead, you either
1)Return the values from the activity using startActivityForResult
or
2)Alter an in memory data structure reachable by both activities, and int he onResume of the original Activity you refresh your views from that data structure.

Button onClickListener causes runtime error without pressing it

I'm trying to make an app where a loop generates arithmetic expressions and list them as individual TextViews in linear layout. After tapping on one of the expressions a popup window comes up with that expression and an input field for the user to input a solution. Underneath there is a button to submit the solution. I have the button positioned in XML. The problem is that when I use onClickListener, the app crashes in the moment when I tap on the expression for the window to popup. If I remove the whole onClickListener then window comes up, but button is functionless.
This causes error:
Button btnDone = (Button) findViewById(R.id.buttonDone);
btnDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
answerWindow.dismiss();
}
});
And this is the rest of the function:
package klosinski.kamil.arithmeticproblems;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.ScrollView;
import android.widget.TextView;
import java.util.Random;
public class QuizGenerate extends AppCompatActivity {
boolean usePlus, useMinus, useMult, useDivide;
int count, maxValue;
Equation equation[] = new Equation[20];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_generate);
SharedPreferences quizSettings = getSharedPreferences("QuizSettings", MODE_PRIVATE);
usePlus = quizSettings.getBoolean("usePlus", true);
useMinus = quizSettings.getBoolean("useMinus", true);
useMult = quizSettings.getBoolean("useMult", true);
useDivide = quizSettings.getBoolean("useDivide", true);
count = quizSettings.getInt("count",0);
maxValue = quizSettings.getInt("maxValue",0);
generateQuiz(); //Populate Equation class with generated equations
displayQuiz(); //Display the equations to the screen
}
//Method to display the contents of Equation class to the screen
public void displayQuiz(){
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollViewx);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(linearLayout);
for(int i = 0; i < count; i++){
int value1 = equation[i].getValue1();
int value2 = equation[i].getValue2();
char operator = equation[i].getOperator();
String value1Str = Integer.toString(value1);
String value2Str = Integer.toString(value2);
TextView textView = new TextView(this);
textView.setTextSize(getResources().getDimension(R.dimen.equationSize));
if(operator == '/'){
operator = '\u00F7';
}
textView.setText(value1Str + " " + operator + " " + value2Str + "=");
textView.setId(i);
textView.setOnClickListener(displayAnswerForm);
textView.setClickable(true);
linearLayout.addView(textView);
}
this.setContentView(scrollView);
}
// OnClickListener runs after equation is pressed.
// Displays a popup window with the pressed equation and editText for answer.
public View.OnClickListener displayAnswerForm = new View.OnClickListener() {
public void onClick(View v) {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.popup_window, null);
// Create the popup window
int width = LinearLayout.LayoutParams.MATCH_PARENT; // Width of the popup window
int height = LinearLayout.LayoutParams.MATCH_PARENT; // Height of the popup window
final PopupWindow answerWindow = new PopupWindow(popupView, width, height, true);
int equationTextViewId= v.getId(); // The ID of the text view that was pressed
// Getting the values and operator to display as equation.
String value1 = Integer.toString(equation[equationTextViewId].getValue1());
String value2 = Integer.toString(equation[equationTextViewId].getValue2());
char operator = equation[equationTextViewId].getOperator();
// If operator is a '/' (divide) then display it as a divider symbol.
if(operator == '/'){
operator = '\u00F7';
}
String equationToDisplay = value1+" "+operator+" "+value2+"="; // Complete string with the equation.
//Display our equation on the popup window.
((TextView)answerWindow.getContentView().findViewById(R.id.answerWindowTextView)).setText(equationToDisplay);
// Display the popup window.
answerWindow.showAtLocation(v, Gravity.CENTER, 0, 0);
////
////
//// setOnClickListener or the function causes a crash.
////
////
Button btnDone = (Button) findViewById(R.id.buttonDone);
btnDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
answerWindow.dismiss();
}
});
}
};
//Method to populate Equation class with generated equations
public void generateQuiz(){
char operator = '+';
for(int i = 0; i < count; i++){
switch(getRandomNumber(1, 4)){
case 1:
operator = '+';
break;
case 2:
operator = '-';
break;
case 3:
operator = '*';
break;
case 4:
operator = '/';
break;
default:
break;
}
equation[i] = new Equation(getRandomNumber(1, maxValue), getRandomNumber(1, maxValue), operator);
}
}
private int getRandomNumber(int min,int max) {
return (new Random()).nextInt((max - min) + 1) + min;
}
}
<?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:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"
android:gravity="center"
android:visibility="visible">
<TextView
android:id="#+id/answerWindowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="5 + 2="
android:textAllCaps="false"
android:textSize="50sp"
app:layout_constraintBottom_toTopOf="#+id/editText8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<EditText
android:id="#+id/editText8"
style="#style/Widget.AppCompat.AutoCompleteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:backgroundTint="#color/colorEditText"
android:ems="10"
android:gravity="center"
android:hint="eg. 28"
android:inputType="number"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.527"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/answerWindowTextView" />
<Button
android:id="#+id/buttonDone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="DONE"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/editText8" />
</android.support.constraint.ConstraintLayout>
Google has lead me to a few "related" topics, but none helped me. Might it be something to do with the View?
Regards,
Kamil
#edit
08-02 15:50:18.731 12741-12741/klosinski.kamil.arithmeticproblems E/AndroidRuntime: FATAL EXCEPTION: main
Process: klosinski.kamil.arithmeticproblems, PID: 12741
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at klosinski.kamil.arithmeticproblems.QuizGenerate$1.onClick(QuizGenerate.java:110)
at android.view.View.performClick(View.java:5698)
at android.widget.TextView.performClick(TextView.java:10846)
at android.view.View$PerformClick.run(View.java:22565)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7230)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
This line at klosinski.kamil.arithmeticproblems.QuizGenerate$1.onClick(QuizGenerate.java:110) tells you that the crash happened at QuizGenerate.java file at line 110
The error java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference suggests that the btnDone is null.
findViewById would work only if the view that you are looking for belongs to the current context in scope. i.e. If you are calling findViewById within an Activity then the view should belong to the activity otherwise it will return null. If you are calling findViewById within a Fragment then the view should belong to the fragment otherwise it will return null. You get the point.
So make sure that you are calling Button btnDone = (Button) findViewById(R.id.buttonDone); from the right place.
You shouldn't use setContentView(); like this. Only call it once, only in onCreate(). If you want to change the content, use fragments or start another activity. if you change the content, you can't find your views via findViewById anymore.

Removing a view or range of views from a LinearLayout causes a NullPointerException in a call to unFocus

I have a HorizontalScrollView containing a LinearLayout which is used to display a file tree ribbon
<HorizontalScrollView
android:id="#+id/content_ribbon_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:scrollbars="none">
<LinearLayout
android:id="#+id/content_file_ribbon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
Items are added to the LinearLayout as the user navigates to them
void addRibbonItem(final Node node) {
final TextView view = (TextView) getLayoutInflater().inflate(R.layout.shard_ribbon_item, mRibbon, false);
view.setText(node.getName());
mRibbon.addView(view);
mRibbon.postDelayed(() -> mRibonScrollView.fullScroll(View.FOCUS_RIGHT), 17);
When an item is clicked, all of the items to the right of it should be removed.
I have tried to do this with the removeViewsInLayout method, as well as repeatedly removing the final view.
(Ignore the lack of bounds checks)
view.setOnClickListener(v -> {
mRibbon.removeViewsInLayout(mRibbon.indexOfChild(view) + 1, mRibbon.getChildCount());
});
view.setOnClickListener((v) -> {
final int index = mRibbon.indexOfChild(view);
for(int i = 0; i < index; i++) mRibbon.removeViewAt(mRibbon.getChildCount());
});
Both of these methods give the same exception
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.unFocus(android.view.View)' on a null object reference
at android.view.ViewGroup.removeViewsInternal(ViewGroup.java:4691)
at android.view.ViewGroup.removeViewsInLayout(ViewGroup.java:4539)
at com.tpb.projects.repo.content.ContentActivity.lambda$-com_tpb_projects_repo_content_ContentActivity_lambda$1(ContentActivity.java:67)
Any help is appreciated.
Edit:
Removing and re-adding the Views does work, but I don't believe that this is a good solution.
view.setOnClickListener(v -> {
final ArrayList<View> views = new ArrayList<>();
for(int i = 0; i <= mRibbon.indexOfChild(view); i++) {
views.add(mRibbon.getChildAt(i));
}
mRibbon.removeAllViews();
for(View item : views) {
mRibbon.addView(item);
}
});
Try this:
1. Use the child element to get a reference to the parent.
2. Cast the parent to a ViewGroup so that you get access to the removeView method and use that.
((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout);
and not like this:
//scrollView.removeView(scrollChildLayout);

How to make phone calls programmatically in Android?

I have the following layout defined in useful_numbers_item_fragment.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/call_linear_layout">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_name"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_value"/>
</LinearLayout>
<ImageButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/call"
android:id="#+id/call_btn"
android:onClick="callNumber"/>
</LinearLayout>
I dynamically populate the two text views in a class called UNItemListFragment.java
in the onCreate method:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
if (getArguments().containsKey(Constants.UNItem.GROUP_ID)) {
simpleCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.useful_numbers_item_fragment, null,
new String[]{Constants.UNItem.NAME, Constants.UNItem.VALUE},
new int[]{R.id.useful_nums_item_name, R.id.useful_nums_item_value}, 0);
setListAdapter(simpleCursorAdapter);
getLoaderManager().initLoader(0, getArguments(), this);
}
}
For each number if i click on the button i want to make a phone call by
calling the callNumber method when the user clicks the button:
public void callNumber(View view) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);
String phoneNumber = unItemVal.getText().toString();
callIntent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
}
It is ok when I click the first button in the list, but when I click on the other buttons
it continues calling the number defined in the first row...
Any idea how to resolve this?
The problem is that this line:
TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);
is executed on the activity, so the findViewById will always return the first item with that id, which is likely the first item in the list.
The best way to fix this would be to override the adapter and add a tag containing the phone number to the view. A quick way to fix this would be to tag along in the view hierarchy, like so:
public void callNumber(View view) {
if( view != null ) { // view is the button tapped
View parent = view.getParent(); // this should be the LinearLayout
if( parent instanceof LinearLayout ) {
TextView unItemVal = (TextView) ((LinearLayout)parent).findViewById(R.id.useful_nums_item_value);
if( unItemVal != null ) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
String phoneNumber = unItemVal.getText().toString();
callIntent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
}
}
}
}
This would find the parent for the button that was clicked, and then find the text-view containing the number within that ViewGroup.
Using findViewById() will return the first view in the activity or fragment with the specified id. If this is a ListView, it will correspond to the first row.
There are many ways to work around this problem. The quickest one (but certainly not the prettiest one, since it depends on the layout) would be to use findViewById() relative to the LinearLayout that contains the list item. Assuming that view is the ImageButton, it would be somthing like:
((View)view.getParent()).findViewById(R.id.useful_nums_item_value)
A more elegant solution would be to set a tag in the adapter's getView(), containing the data you need (in this case, the phone number to call).

Android: Linking Edit Text field to button

I am creating a times tables app, in which one of the activities allows the user to enter which times tables they would like to view, then the app will bring up that times tables.(e.g. 6x5=30) etc.
Below is the xml layout I have created for the activity:
<?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="15dp">
<TextView
android:id="#+id/tvTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I want to see the: "
android:textSize="25dp" />
<EditText
android:id="#+id/etEnterNumber"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter Number..."
>
</EditText>
<TextView
android:id="#+id/tvBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Times tables!"
android:textSize="25dp" />
<Button
android:id="#+id/btnGo"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="Go"
android:layout_gravity="center"/>r
</LinearLayout>
And this it the java class I have created thus far for the classes functionalitiy:
public class ViewTimesTables extends Activity implements View.OnClickListener {
// Declaring Vars
Button go;
EditText enterNumber;
TextView top;
TextView bottom;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setting equal to text layout View
setContentView(R.layout.view);
// calling method to intialise vars
initialiseVars();
}// on create end
/**
* method to initialise all of the buttons, textviews etc used to clean up
* the onCreate.
*/
private void initialiseVars() {
// Setting up (initialising) all the buttons text views etc from the xml
// (vid 25)
go = (Button) findViewById(R.id.btnGo);
enterNumber = (EditText) findViewById(R.id.etEnterNumber);
top = (TextView) findViewById(R.id.tvTop);
bottom = (TextView) findViewById(R.id.tvBottom);
}
/**
* Method with on click listener that adds functionality for all of the
* buttons, text views etc
*
* #param v
*/
public void onClick(View view) {
// switch statement which determines what is clicked
switch ((view).getId()) {
case R.id.etEnterNumber:
// code to read user number (i.e. between 1 and 12)
//And possibly link to go button
break;
case R.id.btnGo:
// code to bring up new activity/screen with times table
// of the number that was entered in edit text
break;
}
}
}
I am unsure how to add the correct functionality (probably within switch statement) so that when e.g. "6" is entered in the edit text box and the "go" button is pressed then the 6 times tables will be brought up in a new activity?
I would begin by looking at Intents to start a new activity and pass data to it.
A relevant tutorial is this Android Intents Tutorial
Getting the text from a edit text is a simple as enterNumber.getText().getString()
You could then use a conditional statement to call the designated class.
Something like this would allow you to pass two values to the SixTimesTables class with the values 5 and 6 passed in.
if(enterNumber.getText().getString().equals("6")){
Intent i = new Intent(this, SixTimesTables.class);
i.putExtra("Value1", 5);
i.putExtra("Value2", 6);
// set the request code to any code you like,
// you can identify the callback via this code
startActivityForResult(i, REQUEST_CODE);
}
You probably want a dynamic layout for next activity.
It may help you.
http://www.dreamincode.net/forums/topic/130521-android-part-iii-dynamic-layouts/
Then you can switch between activities as AndyGable mentioned.
Hopefully it'll help you.
You really dont need the onClick for the editText you can handle if data is entered in the editText or not from the button click only like this:
public void onClick(View view) {
// switch statement which determines what is clicked
switch ((view).getId()) {
case R.id.btnGo:
// code to bring up new activity/screen with times table
// of the number that was entered in edit text
// check if editText has values or not
if(TextUtils.isEmpty(mEditText.getText().toString())) {
mEditText.setError("Please enter a number");
}else {
int number = Integer.parseInt(mEditText.getText().toString());
Intent intent = new Intent(YourCurrentActivity.this, NextActivity.class);
intent.putExtra("value", number);
startActivity(intent);
// it is always good to check if the value entered is a number only or not
// add inputType tag in the xml
// android:inputType="number" for the editText.
}
break;
}
}
Now, in order to get value in the next activity do this:
// write this inside the onCreate of the Activity.
int number;
if(getIntent().getExtras() != null) {
number = getIntent().getIntExtra("value");
}
// use the number then to display the tables

Categories

Resources