Change text in another activity on click. how? - java

I am new to this forum as an User, and I am also new to Java and Android, in developing ways. Sorry if there are any language or other mistakes.
So I am trying to make an app for a 'final' school project, which has the follow use:
The user sees a picture, a 'next' and a 'finish' button. there are 11 pictures (user only sees one) when the user clicks 'next', the pic no. 2 appears, if he clicks another time next, the picture no. 3 appears and so on.
when user clicks next 2 times (so if he made it until the 3rd picture) and then clicks finish, he'll Return to the main activity, and instead of the text 'Klicke auf start um zu beginnen' (click on start to begin) the text 'you made it until the 3rd picture' should show up.
If he clicked Next 5 times (6th picture) and clicks finish, he also returns to the main activity, but the text is 'you made it until the 5th picture'.
And so on with the others.
I've tried this, but I failed.
the red lines are those, which I made at my own but they unfortunately don't work
[B]Java Main Activity[/B]
package ch.OptiLab.visustest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
TextView textView;
Button btn1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button) findViewById(R.id.buttonSTART);
btn1.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivityForResult(new Intent(this,VisusActivity.class), 0);
}
public void onActivityResult() {
if (resultCode == R.drawable.v1)textView.setText("you got 01");
else if (resultCode == R.drawable.v2)textView.setText("you got 02");
else if (resultCode == R.drawable.v3)textView.setText("you got 03");
else if (resultCode == R.drawable.v4)textView.setText("you got 04");
else if (resultCode == R.drawable.v5)textView.setText("you got 05");
else if (resultCode == R.drawable.v6)textView.setText("you got 06");
else if (resultCode == R.drawable.v7)textView.setText("you got 07");
else if (resultCode == R.drawable.v8)textView.setText("you got 08");
else if (resultCode == R.drawable.v9)textView.setText("you got 09");
else if (resultCode == R.drawable.v10)textView.setText("you got 10");
}
]
XML Main Activity
<RelativeLayout xmlns:android="(external link)"
xmlns:tools="(external link)"
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"
tools:context="ch.OptiLab.visustest.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/Text1"
android:id="#+id/textView"
android:layout_marginTop="84dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:gravity="center_horizontal"
android:singleLine="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/Text2"
android:id="#+id/textView2"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="33dp" />
<Button
android:id="#+id/buttonSTART"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="#string/button1"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="142dp" />
</RelativeLayout>
Java 2nd activity
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class VisusActivity extends Activity {
Button next;
ImageView testanzeige;
Button finish;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_visus);
next = (Button)findViewById(R.id.next);
testanzeige = (ImageView)findViewById(R.id.testanzeige);
finish = (Button)findViewById(R.id.finish);
textView = (TextView)findViewById(R.id.textView);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
i++;
// To Set Your 1 Image Do it Thorough Layout
if (i == 1 ) {
//Your 2 Image
testanzeige.setImageResource(R.drawable.v1);
onStop();
setResult(R.drawable.v1);
}
else if (i == 2) {
//Your 3 Image
testanzeige.setImageResource(R.drawable.v2);
onStop();
setResult(R.drawable.v2);
}
else if (i == 3) {
//Your 4 Image
testanzeige.setImageResource(R.drawable.v3);
onStop();
setResult(R.drawable.v3);
}
else if (i == 4) {
// Your 5 Image
//Imagey.setImageResource(R.drawable.Your Image);
testanzeige.setImageResource(R.drawable.v4);
onStop();
setResult(R.drawable.v4);
}
else if (i == 5 ) {
//Your 6 Image
//Imagey.setImageResource(R.drawable.Your Image);
testanzeige.setImageResource(R.drawable.v5);
onStop();
setResult(R.drawable.v5);
}
else if (i == 6) {
//Your 7 Image
//Imagey.setImageResource(R.drawable.Your Image);
testanzeige.setImageResource(R.drawable.v6);
onStop();
setResult(R.drawable.v6);
}
else if (i == 7 ) {
//Your 8 Image
//Imagey.setImageResource(R.drawable.Your Image);
testanzeige.setImageResource(R.drawable.v7);
onStop();
setResult(R.drawable.v7);
}
else if (i == 8 ) {
//Your 9 Image
//Imagey.setImageResource(R.drawable.Your Image);
testanzeige.setImageResource(R.drawable.v8);
onStop();
setResult(R.drawable.v8);
}
else if (i == 9) {
//Your 10 Image
testanzeige.setImageResource(R.drawable.v9);
onStop();
setResult(R.drawable.v9);
}
else if (i == 10) {
//Image 11 Image
testanzeige.setImageResource(R.drawable.v10);
onStop();
setResult(R.drawable.v10);
//next.setText("Finish");
//Toast.makeText(getApplicationContext(), "Your Final Text", Toast.LENGTH_LONG).show();
}
finish.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
});
}
}
XML 2nd Activity
<ImageView
android:id="#+id/testanzeige"
android:layout_width="231dp"
android:layout_height="231dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/v2" />
<Button
android:id="#+id/next"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:text="#string/NEXTPIC" />
<Button
android:id="#+id/finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/next"
android:layout_alignBottom="#+id/next"
android:layout_alignParentLeft="true"
android:text="#string/cantread" />
</RelativeLayout>
The most important strings:
<string name="Text1">Klicke auf Start um zu beginnen.</string>
<string name="cantread">finish</string>
Thank you so much

You have to use startActivityForResult http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int)
You pass two parameters in this function. For the purpose of this example lets assume you pass 2 as the result code.
Now when you're about to finish your second activity, and before you call finish() you can use setResult(position) where position is the image position that you just set. After you call finish your main activity will fire onActivityResult.
On that method you will have to search for the requestCode that you passed (2) and you will get the result code that you used on your setResult.
You can also pass bundles with this method.
EDIT
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == R.drawable.v1)textView.setText("you got 01");
else if (resultCode == R.drawable.v2)textView.setText("you got 02");
else if (resultCode == R.drawable.v3)textView.setText("you got 03");
else if (resultCode == R.drawable.v4)textView.setText("you got 04");
else if (resultCode == R.drawable.v5)textView.setText("you got 05");
else if (resultCode == R.drawable.v6)textView.setText("you got 06");
else if (resultCode == R.drawable.v7)textView.setText("you got 07");
else if (resultCode == R.drawable.v8)textView.setText("you got 08");
else if (resultCode == R.drawable.v9)textView.setText("you got 09");
else if (resultCode == R.drawable.v10)textView.setText("you got 10");
}

You need to pass the last image shown's index for finish button :
Intent in = new Intent(this, MainActivity.class);
in.putExtra("index", i);
startActivity(in);
And in your MainActivity onCreate, check if the data is passed :
Bundle data = getIntent().getExtras();
if(data != null)
int lastIndex = data.getInt("index");
After this, you can do anything with lastIndex, like show it in your TextView.

Related

Android: Setting background of a ImageView to a ClipDrawable results in a Null object error?

I am creating an app in which a user clicks on a Button to input a selected image to an ImageView. Initially, the image is correctly cropped at 50% from the right, as shown in below:
Then, the user can drag the slider to the left to reveal less of the image, or right to reveal more of the image. However, when the user moves the slider, the app crashes, returning the following Null object error on the line of code where I set the ImageView's background to the newly cropped image based on the slider's progress (singlePreviewBox.setBackground(mClipDrawable);).
java.lang.NullPointerException: Attempt to invoke virtual method 'int
android.graphics.drawable.Drawable.getOpacity()' on a null object
reference at
android.graphics.drawable.ClipDrawable.getOpacity(ClipDrawable.java:159)
at android.view.View.computeOpaqueFlags(View.java:15698) at
android.view.View.setBackgroundDrawable(View.java:20502) at
android.view.View.setBackground(View.java:20395) at
com.example.changingimageviewwidth.MainActivity$1.onProgressChanged(MainActivity.java:49)
This seems strange, considering that the code performing the initial 50% crop from the right works, and I used that same code in my slider listener.
Below is my code:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/transition_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<Button
android:id="#+id/photo_input_1"
android:onClick="chooseFile"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:fontFamily="sans-serif"
android:text="No Photo"
android:textAllCaps="false"
android:textSize="16sp"
android:background="#f3f3f3"
android:elevation="4dp"
android:layout_margin="4dp"
android:minHeight="40dp"/>
<SeekBar
android:id="#+id/image_reveal_slider"
style="#style/Widget.AppCompat.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:progress="5" />
<ImageView
android:id="#+id/image_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="370dp"
android:adjustViewBounds="true"/>
</LinearLayout>
MainActivity.java:
package com.example.changingimageviewwidth;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Toast;
import java.io.InputStream;
public class MainActivity extends Activity
{
// Request code used when reading in a file
private Integer READ_IN_FILE = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SeekBar imageRevealSlider = (SeekBar) findViewById(R.id.image_reveal_slider);
// perform seek bar change listener event used for getting the progress value
imageRevealSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int progressChangedValue = 0;
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressChangedValue = progress;
ImageView singlePreviewBox = findViewById(R.id.image_container);
singlePreviewBox.invalidate();
ClipDrawable mClipDrawable = new ClipDrawable(singlePreviewBox.getDrawable(), 11,
ClipDrawable.HORIZONTAL);
mClipDrawable.setLevel((progress / 10) * 10000);
singlePreviewBox.setImageResource(0);
singlePreviewBox.setBackground(mClipDrawable);
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this, "Seek bar progress is :" + progressChangedValue,
Toast.LENGTH_SHORT).show();
}
});
}
public void chooseFile(View v) {
// Specify that only photos are allowed as inputs (.jpg, .png).
Intent photoInputSpecs = new Intent(Intent.ACTION_GET_CONTENT);
photoInputSpecs.setType("image/*");
Intent photoInputHandler = Intent.createChooser(photoInputSpecs, "Choose a file");
startActivityForResult(photoInputHandler, READ_IN_FILE);
}
// Processes the results of Activities.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
// Processes the photos that the user selected
if (requestCode == READ_IN_FILE) {
// Retrieve the photo's location
Uri photoUri = data.getData();
InputStream photoInputStream = getContentResolver().openInputStream(photoUri);
System.out.println("[photoInputStream.available()] = " + photoInputStream.available());
Bitmap photoBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),
photoUri);
// Display the selected image in the preview box
displayPhoto(photoUri);
}
}
catch (Exception ex) {
System.out.println("onActivityResult error: " + ex.toString());
}
}
// Displays a specified photo in the split and single screen preview boxes.
private void displayPhoto(Uri photoUri) {
ImageView singlePreviewBox = findViewById(R.id.image_container);
singlePreviewBox.invalidate();
singlePreviewBox.setImageURI(photoUri);
ClipDrawable mClipDrawable = new ClipDrawable(singlePreviewBox.getDrawable(), 11,
ClipDrawable.HORIZONTAL);
mClipDrawable.setLevel(5000);
singlePreviewBox.setImageResource(0);
singlePreviewBox.setBackground(mClipDrawable);
}
}
I noticed several problems with your code.
Null Pointer Exception
If your ImageView has no image, your app will crash. This is something that you need to check beforehand.
Math
mClipDrawable.setLevel((progress / 10) * 10000); Division between integers might causes a faction loss. So you either have to cast one of them or both; like this one.
mClipDrawable.setLevel((int)((progress / 10F) * 10000F));
The Use of Methods
singlePreviewBox.setImageResource(0); You're setting an image to your ImageView, soon after you're setting it with a different method. You don't even need this method by the way. Even the use of this method is incorrect. It supposed to look like this:
singlePreviewBox.setImageResource(R.drawable.myImage);

Android Material Button Toggle Group

I'm creating a form in android which asks for gender. To get this input I use Material Button Toggle Group which contains two buttons. I don't know how to know which button is clicked in my activity.java. How to get to know about the selected button in my activity so that i can save the details in different database.
myxml.xml
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="#+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:singleSelection="true">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Male"
android:layout_marginStart="5dp"
style="?attr/materialButtonOutlinedStyle"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Female"
android:layout_marginStart="10dp"
style="?attr/materialButtonOutlinedStyle"/>
</com.google.android.material.button.MaterialButtonToggleGroup>
Myactivity.java
MaterialButtonToggleGroup toggleButton = findViewById(R.id.toggleButton);
toggleButton.addOnButtonCheckedListener();
// I CAN'T FIND ANY PROPER SOLUTION
You can use the getCheckedButtonId() method.
Something like:
MaterialButtonToggleGroup materialButtonToggleGroup =
findViewById(R.id.toggleButton);
int buttonId = materialButtonToggleGroup.getCheckedButtonId();
MaterialButton button = materialButtonToggleGroup.findViewById(buttonId);
Only if you need a listener you can use the addOnButtonCheckedListener:
materialButtonToggleGroup.addOnButtonCheckedListener(new MaterialButtonToggleGroup.OnButtonCheckedListener() {
#Override
public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
if (isChecked) {
if (checkedId == R.id.button1) {
//..
}
}
}
});
You have to check the checkedId value but also the isChecked value. The same listener is called when you check a button but also when you unckeck a button.
It means that if you click the button1 the listener is called with isChecked=true and checkedId=1. Then if you click the button2 the listener is called twice. Once with isChecked=false and checkedId=1, once with isChecked=true and checkedId=2.
You can do it like this :
toggleButton.addOnButtonCheckedListener(new MaterialButtonToggleGroup.OnButtonCheckedListener() {
#Override
public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
if(group.getCheckedButtonId()==R.id.button1)
{
//Place code related to button1 here
Toast.makeText(MainActivity2.this, "Button1 Clicked", Toast.LENGTH_SHORT).show();
}else if(group.getCheckedButtonId()==R.id.button2) {
//Place code related to button 2 here
Toast.makeText(MainActivity2.this, "Button2 Clicked", Toast.LENGTH_SHORT).show();
}
}
});

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.

Android multitouch issue

So I'm working on a game where two players play simultaneously on one screen. For the sake of simplicity let's say both players have one button on their side of the screen, buttons B[0] and B[1]. I want to implement multitouch so that both buttons can be pressed with no unresponsiveness, but as soon as one of them does ACTION_DOWN on his button, the other one becomes unresponsive. I read all the duplicate questions and understood that the second touch would be referenced as ACTION_POINTER_DOWN so I wrote this piece of code:
#Override
public boolean onTouch(View buttonPressed, MotionEvent action)
{
if(buttonPressed.getId()==B[0].getId())
{
if(action.getAction() == MotionEvent.ACTION_DOWN || action.getAction() == MotionEvent.ACTION_POINTER_DOWN)
B[0].setImageDrawable(BPressed[0]);
if(action.getAction() == MotionEvent.ACTION_UP || action.getAction() == MotionEvent.ACTION_POINTER_UP)
B[0].setImageDrawable(BOk[0]);
}
if(buttonPressed.getId()==B[1].getId())
{
if(action.getAction() == MotionEvent.ACTION_DOWN || action.getAction() == MotionEvent.ACTION_POINTER_DOWN)
B[1].setImageDrawable(BPressed[1]);
if(action.getAction() == MotionEvent.ACTION_UP || action.getAction() == MotionEvent.ACTION_POINTER_UP)
B[1].setImageDrawable(BOk[1]);
}
return true;
}
So as far I can tell if I put 1 finger on B[0] and leave it there (no ACTION_UP) and then put another on B[1] the listener should fire onTouch(B[1],ACTION_POINTER_DOWN) but i think it doesn't since when I do that B[0] has BPressed drawable and B[1] has BOk drawable. Where did I go wrong? Sorry if I made a duplicate, but I read everything and can't seem to find a simple solution. Every solution regarding this issue I found gives much more than I need.
Both buttons are connected with the listener like this:
B[0].setOnTouchListener(this);
B[1].setOnTouchListener(this);
I've read this:
ACTION_POINTER_DOWN and ACTION_POINTER_UP are fired whenever a secondary pointer goes down or up.
But it doesn't seem to be true.
EDIT:
The new code, still the same result:
#Override
public boolean onTouch(View buttonPressed, MotionEvent action)
{
if( buttonPressed.getId()==B[1].getId() )
Toast.makeText(context, "One", 500).show();
int act = action.getAction() & MotionEvent.ACTION_MASK;
if(buttonPressed.getId()==B[0].getId())
{
if(act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_POINTER_DOWN)
B[0].setImageDrawable(BPressed[0]);
if(act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP)
B[0].setImageDrawable(BOk[0]);
}
if(buttonPressed.getId()==B[1].getId())
{
if(act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_POINTER_DOWN)
B[1].setImageDrawable(BPressed[1]);
if(act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP)
B[1].setImageDrawable(BOk[1]);
}
return true;
}
Also, the toast:
if( buttonPressed.getId()==B[1].getId() )
Toast.makeText(context, "One", 500).show();
can never be seen if I keep my finger on B[0].
After masking:
Something changed. Let's say I hold my finger on B[0]. Before the masking when I press B[1] nothing happens. After masking if I keep my finger on B[0], and I tap my finger ANYWHERE on the screen it cycles the B[0]. So if I go:
finger1_DOWN on B[0] it changes to Pressed drawable
while(1)
{
finger2_DOWN anywhere nothing changes
finger2_UP anywhere B[0] changes to Ok drawable
}
I create my imagebuttons in OnCreate:
B[0] = (ImageButton) findViewById(R.id.ImageButton05);
B[0].setOnTouchListener(this);
B[1] = (ImageButton) findViewById(R.id.ImageButton15);
B[1].setOnTouchListener(this);
I tried jboi's approach. I don't care if the button was pressed first or second so I just did this:
private class MPListener implements OnTouchListener
{
#Override
public boolean onTouch(View buttonPressed, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(buttonPressed.getId()==B[0].getId())
B[0].setImageDrawable(BPressed[0]);
if(buttonPressed.getId()==B[1].getId())
B[1].setImageDrawable(BPressed[1]);
}
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(buttonPressed.getId()==B[0].getId())
B[0].setImageDrawable(BOk[0]);
if(buttonPressed.getId()==B[1].getId())
B[1].setImageDrawable(BOk[1]);
}
return true;
}
}
I removed implements onTouchListener from my activity and added
B[0].setOnTouchListener(new MPListener());
B[1].setOnTouchListener(new MPListener());
Nothing changed. I can still press both buttons independently, but not at the same time.
EDIT:
So I made a fresh new activity in case something else was the problem. Here's my new activity's full code:
package com.example.projectname;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class About extends Activity
{
private class MPListener implements OnTouchListener
{
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(v.getId()==B[0].getId())
B[0].setImageDrawable(Bok[0]);
if(v.getId()==B[1].getId())
B[1].setImageDrawable(Bok[1]);
}
else if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(v.getId()==B[0].getId())
B[0].setImageDrawable(Bpressed[0]);
if(v.getId()==B[1].getId())
B[1].setImageDrawable(Bpressed[1]);
}
return true;
}
}
ImageView[] B;
Drawable[] Bok,Bpressed;
#Override
protected void onCreate(Bundle savedInstanceState)
{
//standard oncreate stuff
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_about);
Context context=getApplicationContext();
B=new ImageView[2];
Bok=new Drawable[2];
Bpressed=new Drawable[2];
Bok[0] = context.getResources().getDrawable(R.drawable.bblue);
Bok[1] = context.getResources().getDrawable(R.drawable.bpurp);
Bpressed[0] = context.getResources().getDrawable(R.drawable.bpressedblue);
Bpressed[1] = context.getResources().getDrawable(R.drawable.bpressedpurp);
B[0] = (ImageView) findViewById(R.id.imageView1);
B[1] = (ImageView) findViewById(R.id.imageView2);
B[0].setImageDrawable(Bok[0]);
B[1].setImageDrawable(Bok[1]);
B[0].setOnTouchListener(new MPListener());
B[1].setOnTouchListener(new MPListener());
}
}
Everything is the same as always. As soon as I press one button the other one goes unresponsive.
Android can sort out for you, what was pressed in what order and if it is still touched or not. Just give the two Buttons different listeners. Something like this code:
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("TEST", "Begin onCreate");
super.onCreate(savedInstanceState);
Log.d("TEST", "End onCreate");
setContentView(R.layout.test);
findViewById(R.id.upperTouchable).setOnTouchListener(new MyTouchListener());
findViewById(R.id.lowerTouchable).setOnTouchListener(new MyTouchListener());
}
private boolean lowerIsTouched = false;
private boolean upperIsTouched = false;
private void setInfo() {
if(lowerIsTouched && upperIsTouched)
((TextView) findViewById(R.id.info)).setText("both touched");
else if(lowerIsTouched)
((TextView) findViewById(R.id.info)).setText("only lower is touched");
else if(upperIsTouched)
((TextView) findViewById(R.id.info)).setText("only upper is touched");
else
((TextView) findViewById(R.id.info)).setText("non is touched");
((TextView) findViewById(R.id.lowerTouchable)).setText(lowerIsTouched? "touched":"not touched");
((TextView) findViewById(R.id.upperTouchable)).setText(upperIsTouched? "touched":"not touched");
}
private class MyTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
if(v.getId() == R.id.lowerTouchable)
lowerIsTouched = true;
else if(v.getId() == R.id.upperTouchable)
upperIsTouched = true;
setInfo();
}
else if(event.getAction() == MotionEvent.ACTION_UP) {
if(v.getId() == R.id.lowerTouchable)
lowerIsTouched = false;
else if(v.getId() == R.id.upperTouchable)
upperIsTouched = false;
setInfo();
}
return true;
}
}
and the corresponding layout:
<?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" >
<TextView
android:id="#+id/info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#FFFFFFFF"
android:text="Non touched"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/upperTouchable"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="Not touched"
android:background="#FFF0F0F0"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/lowerTouchable"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="Not touched"
android:background="#FFFFFFFF"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

Camera Intent ACTION_IMAGE_CAPTURE and put extra data

I want to put extra data to an Intent Camera, that seems simple...
It WAS working some days ago, but I made a lot of changes on code, avd and target version and now it is not working.
The project is now on target version 11.
In fact my goal is to pass an id from my database to construct image name but here a simple code to illustrate my issue.
Here's the sample code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android: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=".CameraTestActivity" >
<Button
android:id="#+id/buttonpic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="76dp"
android:text="Button" />
</RelativeLayout>
-
public class CameraTestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_test);
Button buttonpic = (Button)findViewById(R.id.buttonpic);
buttonpic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
///first try to put extra data
cameraIntent.putExtra("thisone", "ArgumentFrom");
///second try to put extra data
Bundle extras = new Bundle();
extras.putBoolean("thisalso",true);
cameraIntent.putExtras(extras);
///start camera activty with ID
startActivityForResult(cameraIntent, 1888);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
///if pic is picked and Intent ID is Camera one i.e. 1888
if (requestCode == 1888 && resultCode == RESULT_OK) {
///first try >> Not working
Bundle extra = getIntent().getExtras();////
if (extra != null) {
Log.d("extra: ","isnotnull");
Boolean inputThatIwant = extra.containsKey("thisone");
Boolean inputThatIwantBool = extra.containsKey("thisalso");
Log.d("thisone",inputThatIwant.toString());
Log.d("thisalso",inputThatIwantBool.toString());
}
///Second try >> Some Data is back (pic data... ?)
Bundle extras = data.getExtras();
if (extras != null) {
Log.d("extras: ","isnotnull"); /////-->>Print "isnotnull"
Boolean inputThatIwant = extras.containsKey("thisone");
Boolean inputThatIwantBool = extras.containsKey("thisalso");
Log.d("thisone",inputThatIwant.toString()); /////-->>Print "false"
Log.d("thisalso",inputThatIwantBool.toString()); /////-->>Print "false"
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.camera_test, menu);
return true;
}
}
[EDIT]
Here how I deal with this finally, it can help someone perhaps...
I just "share" within the same class my ID:
private String inputid;
When it's called by Camera request I fill the id in the inputid String and obviously on OnresultActivity this String could not be null, so it works as simple as that...
But if someone has a better solution I'll take it!
Regards....
I don't if its a good prog idea but i created the Uri which i was passing in the intent as a private static member for this class and created a public static function to return this Uri and since in my case I was getting back the result in one of the fragment class of this class , in its(fragment's class) onActivityResult instead of using the the Intent Data parameter which was null(as i found) i used that Uri directly by calling the function(that i created to return Uri). And.... it worked :)

Categories

Resources