About variables and screen touch events - java

I'm rather new to all this, so please bear with me.
what I want to do: interchange the position of two squares on the screen as soon as the user touches the screen.
what I've done so far: in my layout xml, I've used a frame layout end defined the two squares:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frame1"
android:layout_width="260dp"
android:layout_height="540dp"
android:layout_gravity="center_horizontal" >
<EditText
android:id="#+id/square1"
android:enabled="false"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/textlines"
android:clickable="false"
android:gravity="center"
android:inputType="none"
android:text="#string/C1"
android:textSize="25sp" />
<EditText
android:id="#+id/square2"
android:enabled="false"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/textlines"
android:clickable="false"
android:gravity="center"
android:inputType="none"
android:text="#string/C2"
android:textSize="25sp" />
Then in Java, I've done the following:
public class Activity1 extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
EditText square1 = (EditText) findViewById(R.id.square1);
int cc1x = 210;
int cc1y = 410;
square1.setX(cc1x);
square1.setY(cc1y);
EditText square2 = (EditText) findViewById(R.id.square2);
int cc2x = 310;
int cc2y = 410;
square2.setX(cc2x);
square2.setY(cc2y);
int ccdumx = 410;
int ccdumy = 410;
}
In order to get the initial screen - so far so good. The two variables ccdumx and ccdumy are just there for an intermediate storage of one of the two squares when interchanging them
So now I add an event listener to detect a screen touch, followed by the changing of the coordinate variables:
#Override
public boolean onTouchEvent(MotionEvent event) {
ccdumx = cc1x;
ccdumy = cc1y;
cc1x = cc2x;
cc1y = cc2y;
cc2x = ccdumx;
cc2y = ccdumy;
square1.setX(cc1x);
square1.setY(cc1y);
square2.setX(cc2x);
square2.setY(cc2y);
}
but then the variables aren't recognized, nor are the squares' names. When I declare them all again in this bloc, it does work, but then my logic only works one time; I can't switch the squares back, since the variables of the coordinates are always reset by the declaration, followed by the switch of positions... I'm kinda stuck here I was thinking maybe switching first to another activity, but then again, I might have the same problem there... Any help is most appreciated.
PS. I hope the formatting of the code turns out ok, first timer for me. If not, please accept my apologies.

Because all these variables are local to method onCreate(). You need to define them globally to whole class, i.e. outside method onCreate().
The java code in first block of your question should be changed to this.
public class Activity1 extends ActionBarActivity {
int cc1x, cc1y, cc2x, cc2y, ccdumx, ccdumy;
EditText square1, square2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
square1 = (EditText) findViewById(R.id.square1);
cc1x = 210;
cc1y = 410;
square1.setX(cc1x);
square1.setY(cc1y);
square2 = (EditText) findViewById(R.id.square2);
cc2x = 310;
cc2y = 410;
square2.setX(cc2x);
square2.setY(cc2y);
ccdumx = 410;
ccdumy = 410;
}
//... rest of the code

You could just make your variables Global
like this
EditText square1;
EditText square2;
int cc1x;
....
protected void onCreate(Bundle savedInstanceState){
square1 = (EditText) findViewById(R.id.square1);
.....
}

Related

Building a variable upon buttons to trigger listeners

I am breaking my head dealing with variables types in my app.
I try in a loop to increase a var and pass it to a listener, according to the name of the buttons defined in my XML layout.
I would like to start from "jeton1" to "jeton2","jeton3"...., but cannot manage to do that in my code (errors arising), the vars do not point to the buttons stored in the XML and not showing up when calling the buttons listeners.
I made a test with a defined array but the stuff failed.
Test code below made upon only one button.
A help would be greatly appreciated.
Here is my code
The XML layout :
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="20"
android:columnCount="9">
<Button
android:id="#+id/jeton1"
android:layout_column="0"
android:layout_row="0"
android:text="#string/boutona"
android:layout_height="88dp"
android:layout_width="88dp"
android:textSize="40sp"
android:backgroundTint="#eeceac"
android:textStyle="bold" />
Main Java :
public class MainActivity extends AppCompatActivity {
int i;
String jeton = "";
#SuppressLint("ClickableViewAccessibility")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Main loop
for (i = 1; i < 2; i++) {
jeton = "jeton" + i; // Should throw "jeton1", "jeton2".....
final Button jetonnew;
jetonnew = (Button) findViewById(R.id.jeton); // Error 'cannot resolve symbol
// jetonnew = (Button)findViewById(R.id.jeton+i);
// Step 4 Listener
jetonnew.setOnTouchListener(
new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
jetonnew.getBackground().setAlpha(0); // Crash app
jetonnew.setTextColor(Color.parseColor("#2aa17b"));
break;
}
return true;
}
});
}
}
}
Many thanks for your replies and suggestions.
If you have a fixed number of buttons, you can store an array of integers
int[] ids = {R.id.button1, R.id.button2, ...};
However, if you want to dynamically add buttons, you should try creating them programmatically
Button newButton = new Button(this);
or you can create some custom layout and inflate it
inflate(this, R.layout.customLayout, null);
Keep in mind that R.id.someId returns and integer not a string so you cannot append to it. Also adding a string after id does not work for the same reason.
jetonnew = (Button)findViewById(R.id.jeton+i);
This portion of code does not work because R.id.jeton is a generated integer not a string.
You should consider using findViewByTag instead of findViewById. Your code will look like this:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="20"
android:columnCount="9">
<Button
android:tag="jeton1"
android:layout_column="0"
android:layout_row="0"
android:text="#string/boutona"
android:layout_height="88dp"
android:layout_width="88dp"
android:textSize="40sp"
android:backgroundTint="#eeceac"
android:textStyle="bold" />
So in your java file:
for (i = 1; i < 2; i++) {
jeton = "jeton" + i; // Should throw "jeton1", "jeton2".....
final Button jetonnew;
//findViewByTag here
jetonnew = (Button) findViewByTag(jeton)
Another way is to just iterate through GridLayout child, like this:
//suppose your gridLayout has id=#+id/gridparent
GridLayout gridParent = (GridLayout)findViewById(R.id.gridparent);
for(int index=0; index<gridParent.getChildCount(); ++index) {
Button nextButton = (Button)gridParent.getChildAt(index);
//attach listener here
}
You should create arrays of your grid button id's.
#IntegerRes int [] resourceButtonIds = new int[]{R.id.jeton1,R.id.jeton2};
Then modify the loop accordingly.
for (i = 0; i < resourceButtonIds.length; i++) {
final Button jetonnew;
jetonnew = (Button) findViewById(resourceButtonIds[i]);
// now set all your listeners
}
If you want to find the id of the button by using its name:
jetonnew = findViewById(getResources().getIdentifier("jeton" + i, "id", getPackageName()));

My SecondActivity crashes when have more than Three ImageButton is placed

When i am placing three images in my activity it crashes.Can't able to find out
the issue.
First activity
public class SquareMain extends AppCompatActivity {//MainActivity
private boolean isUserClickedBackButton = false;
#Override
protected void onCreate(Bundle savedInstanceState) {//OnCreate
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_square_main);
mainmusic();
}//OnCreate
public void presshere(View view)//pressherebutton
{
Intent press = new Intent(SquareMain.this, SquareHome.class);
startActivity(press);
}//pressherebutton
public void mainmusic(){//mainmusic
MediaPlayer mainmusic = MediaPlayer.create(SquareMain.this, R.raw.mainmeunsong);//main music
mainmusic.start();//main music
mainmusic.setLooping(true);//main music
}
}//MainActivity
Second activity
public class SquareHome extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_square_home);
}
}
Image button
<ImageButton
android:id="#+id/pressherebutton"
android:layout_width="161dp"
android:layout_height="28dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="#mipmap/squarepresshere"
android:onClick="presshere"
android:scaleType="centerCrop"
android:text="#string/presshere"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.86"
app:srcCompat="#drawable/squarepresshere"
tools:layout_editor_absoluteY="223dp" />
my SecondActivity crashes when more than three image button is placed.
Anyone that might have any idea on how to solve this?
What is the size of those images?? Size of an images is also the factors we have to consider for smooth and comfortable to render images. High resolution images may cause ANR.
You need to terminate your MediaPlayer before leaving the Activity, override onPause method and stop your MediaPlayer. declare your mainmusic as class variable not local.
#Override
protected void onPause() {
super.onPause();
if (mainmusic != null) {
if (mainmusic.isPlaying())
mainmusic.stop();
mainmusic.reset();
mainmusic.release();
}
}

Getting a decimal number from EditText on Android Studio

EDIT:Solved!
I know this has been posted before, but the answers I've seen from those are not working for me.
I'm trying to get the input from one textfield (which i've specified as a decimal input) but can't think of any other way to get the value of it other than to toString it.
What I have below crashes and the error logs say
java.lang.IllegalStateException: Could not execute method of the activity
public void buttonOnClick(View v){
// do something when the button is clicked
Double inputNum;
TextView mField = (TextView) findViewById(R.id.mField);
TextView kmField = (TextView) findViewById(R.id.kmField);
if(mField.length() > 0){
inputNum = ( Double.valueOf(kmField.getText().toString()) )/ 0.62137;
mField.setText(inputNum.toString());
}
}
java.lang.IllegalStateException: Could not execute method of the
activity
Possible reason that this issue occur is kmField.getText().toString() return null. So please put some validation over here for kmField
public void buttonOnClick(View v){
// do something when the button is clicked
Double inputNum;
TextView mField = (TextView) findViewById(R.id.mField);
TextView kmField = (TextView) findViewById(R.id.kmField);
if(kmField.getText().toString().isEmpty()){
inputNum = ( Double.valueOf(kmField.getText().toString()) )/ 0.62137;
mField.setText(inputNum.toString());
}
}
xml file:
<EditText
android:id="#+id/editS0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/S0"
android:inputType="numberDecimal" />
<Button
android:id="#+id/getS0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/setS0" />
in your java file:
EditText textS0 = (EditText)findViewById(R.id.editS0);
Button btn_S0 = (Button)findViewById(R.id.getS0);
btn_S0.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
double S0 = Double.parseDouble(textS0.getText().toString());
}
});

Creating a Singleton CountDownTimer in Android

I'm a beginner in android and I've written an activity. It contains a CountDownTimer that counts down from a particular value. It also contains a Button that loads text information and a textview to display count.
Below is the code for Activity1:
public class Screen extends Activity1 implements OnClickListener {
private static final int MILLIS_PER_SECOND = 1000;
private static final int SECONDS_TO_COUNTDOWN = 1;
TextView Time;
int totaltime;
Button startTimer, howTo, pause;
protected CountDownTimer MyTimer;
int PracticeCount;
long tot;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.pushupscreen);
getRefs();
getSpeed();
getCount();
setTotalTime();
startTimer.setOnClickListener(this);
pause.setOnClickListener(this);
}
private void getRefs() {
// Initialize layout resources
Time = (TextView) findViewById(R.id.tvTime);
startTimer = (Button) findViewById(R.id.bStart);
howTo = (Button) findViewById(R.id.btHowTo);
pause = (Button) findViewById(R.id.bPause);
howTo.setOnClickListener(this);
}
private void getTheCount() {
//get count from SharedPreferences
}
private void getSpeed() {
//get speed from SharedPreferences
}
private void setCount(){
totalTime=speed*count;}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == startTimer) {
try {
showTimer(time);
} catch (NumberFormatException e) {
// method ignores invalid (non-integer) input and waits
// for something it cant use
}
} else if (v == pause) {
MyTimer.cancel();
Timer.setText("Resume");
} else if (v == howTo) {
//Launch screen containing information
}
}
private void showTimer(long time) {
if (MyTimer != null) {
MyTimer.cancel();
}
MyTimer = new CountDownTimer(tot2, MILLIS_PER_SECOND) {
#Override
public void onTick(long millisUntilFinished) {
tot = millisUntilFinished;
long seconds = millisUntilFinished / 1000;
Time.setText(String.format("%02d", seconds / 60) + ":"
+ String.format("%02d", seconds % 60));
}
#Override
public void onFinish() {
Time.setText("KABOOM!");
}
}.start();
}
}
And here is the layout file for this:
<TextView
android:id="#+id/tvTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:gravity="center"
android:padding="10dip"
android:text="#string/starttime"
android:textSize="60sp" />
<Button
android:id="#+id/bStart"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_above="#+id/tvTime"
android:text="Start" />
<Button
android:id="#+id/bPause"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_above="#+id/tvTime"
android:layout_toRightOf="#+id/btHowTo"
android:text="Pause" />
<TextView
android:id="#+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/btHowTo"
android:layout_centerHorizontal="true"
android:layout_marginTop="39dp"
android:text="25"
android:textSize="80sp"
android:textAlignment="center"/>
My questions:
1.How do I create 4 activities that use the same layout and the same timer? Each Activity loads a different content in the textview and a different screen on the click of HowTo button.
2.How can Activity1 be designed to run for 1/4th the time set and pass remaining time to Activity2? Is it possible?
I would really appreciate any help and advice that you can provide. Thanks.
A couple things here.
Its very easy to re-use layouts. In each activity's onCreate you would just call:
setContentView(R.layout.pushupscreen); The pushupscreen.xml file can be shared across all activities this way.
What you probably want to do is persist a timestamp to some common data source for all the activities. This could be a write to a SharedPreferences file: Documentation here. Then as each activity resumes, check how much time has already passed by comparing this timestamp to the current timestamp. You could also pass the timestamp as an extra in the intent to start up the subsequent activities. The documentation for that can be found here and here
You could make a custom control, which is basically a new class which inherits some other control's class (for example a LinearLayout or a RelativeLayout). You could then load a view's XML to your new layout or programmatically create new controls inside your control. More info here:
Custom components in Android
After a 1/4 of your countdown period, you can create and send an Intent to start a new activity in the onTick method. You can also put the remaining 3/4 as a millisecond value (of type long) in an intent extra. You can then obtain this value in the new activity and invoke a custom CountDownTimer child there for the rest of your countdown. Then you can finally execute what you wish after the countdown is done in the onFinish() method.

Showing software keyboard with GLSurfaceView (and getting input from it)

I want to get user input for my OpenGL ES 2.0 application, but there are 2 problems:
1) How can I bring the software keyboard to the front of my app?
2) How can I catch input from it?
I tried to use this:
//OpenGL ES 2.0 view class
public class OGLES2View extends GLSurfaceView
{
private static final int OGLES_VERSION = 2;
private static Handler softKeyboardHandler;
private final static int SHOW_IME_KEYBOARD = 0;
private final static int HIDE_IME_KEYBOARD = 1;
private static EditText textEdit;
private static InputMethodManager imm;
private void setSoftKeyboardHandler()
{
softKeyboardHandler = new Handler()
{
public void handleMessage(Message msg)
{
switch(msg.what)
{
case SHOW_IME_KEYBOARD:
textEdit.requestFocus();
imm.showSoftInput(textEdit,inputMethodManager.SHOW_IMPLICIT);//Nothing happens
Log.i("GLVIEW","SHOW KEYBOARD");
break;
case HIDE_IME_KEYBOARD:
imm.hideSoftInput(textEdit, 0);
Log.i("GLVIEW","HIDE KEYBOARD");
break;
default:
break;
}
}
};
}
public OGLES2View(Context context)
{
super(context);
textEdit = new EditText(context);
setEGLContextClientVersion(OGLES_VERSION);
setRenderer(new OGLES2Renderer());
imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
setSoftKeyboardHandler();
}
public static void showIMEKeyboard()
{
softKeyboardHandler.sendEmptyMessage(SHOW_IME_KEYBOARD);
}
public static void hideIMEKeyboard()
{
softKeyboardHandler.sendEmptyMessage(HIDE_IME_KEYBOARD);
}
//In main activity class
private GLSurfaceView ogles2SurfaceView = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//...
ogles2SurfaceView = new OGLES2View(this);
setContentView(ogles2SurfaceView);
}
Handler gets messages, but I got no software keyboard.
To catch text, I wrote some class:
public class TextInputWatcher implements TextWatcher
and:
textEdit.addTextChangedListener(/*TextInputWatcher instance*/);
Or extend a TextEdit so it catches inputed text on back or enter key.
P.S. I got a tablet - transformer, so there is a hardware keyboard attached. I tried with it and without, but no difference. So bonus question - if there is a hardware keyboard will it prevent a software keyboard from popping up and how can input be gotten from it then?.
Show keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Hide keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
I made 2d game. I think you have the same problem like me before. Try this:
class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
private static DrawThread _thread;
public DrawingPanel(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
_thread = new DrawThread(getHolder(), this);
}
....
Layout 'gameview':
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- YOUR SURFACE -->
<com.yourcompany.DrawingPanel android:id="#+id/surfaceView" android:layout_width="fill_parent"
android:layout_height="fill_parent"></com.yourcompany.DrawingPanel>
<!-- YOUR BUTTONS -->
<RelativeLayout android:id="#+id/controlPanel" android:layout_width="fill_parent" android:orientation="horizontal"
android:layout_height="fill_parent" >
<RelativeLayout android:layout_width="50px" android:orientation="vertical"
android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_alignParentLeft="true">
<Button android:id="#+id/leftButton" android:layout_width="wrap_content"
android:layout_height="50px" android:background="#xml/button_left_state"/>
<Button android:id="#+id/upgradeButton" android:layout_width="wrap_content"
android:layout_below="#id/leftButton"
android:layout_height="50px" android:background="#xml/button_upgrade_state"/>
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
Then you should set content in game activity like below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameview);
...
Hope It helps you.

Categories