I am new to Android programming, but I'm quite familiar with Java and so...
In this app, I need to create something like a Death/Birth counter and a Total Population Counter, so I need the String at the Activity to be updated each second, but I can't seen to find any solution.
This is my Main Activity :
public class MainActivity extends ActionBarActivity {
static int nasc;
static int mortes;
static int popTotal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
nasc = 0;
mortes = 0;
popTotal = 0;
setContentView(R.layout.activity_main);
final TextView view = new TextView(this);
Boolean menu = false;
Handler handler = new Handler();
while (menu == false) {
handler.postDelayed(new Runnable() {
public void run() {
view.setText("Births : " + getNasc() + ".");
view.append("\n");
view.append("Deaths : " + getMortes() + ".");
view.append("\n");
view.append("Total Population : " + getPopTotal() + ".");
setContentView(view);
}
}, 1000);
}
}
private int getPopTotal() {
popTotal = nasc - mortes;
return popTotal;
}
private int getMortes() {
mortes = (int) (mortes + 1.7);
return mortes;
}
private int getNasc() {
nasc = nasc + 3;
return nasc;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.textView) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
What have I been doing wrong?
What you need to do is remove the while loop, and just re-run the Runnable if menu == false each second after updating the UI with the new totals.
I just got this implementation working by making the Runnable a member variable instead of it being an anonymous class, using a StringBuilder to build up the text for the TextView, and re-running the Runnable if menu is still false at the completion of each run.
public class MainActivity extends ActionBarActivity {
static int nasc;
static int mortes;
static int popTotal;
TextView view;
Handler handler;
Boolean menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nasc = 0;
mortes = 0;
popTotal = 0;
view = (TextView) findViewById(R.id.text);
menu = false;
handler = new Handler();
handler.postDelayed(updateText, 1000);
}
public Runnable updateText = new Runnable() {
#Override
public void run() {
StringBuilder sb = new StringBuilder();
sb.append("Births : " + getNasc() + ".");
sb.append("\n");
sb.append("Deaths : " + getMortes() + ".");
sb.append("\n");
sb.append("Total Population : " + getPopTotal() + ".");
view.setText(sb.toString());
if (menu == false){
handler.postDelayed(this, 1000);
}
}
};
//.................
activity_main.xml:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:id="#+id/text" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Try this :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
nasc = 0;
mortes = 0;
popTotal = 0;
setContentView(R.layout.activity_main);
final TextView view = (TextView)findViewById(R.id.textView_id);
String allText="";
Boolean menu = false;
Handler handler = new Handler();
while (menu == false) {
handler.postDelayed(new Runnable() {
public void run() {
allText+="Births : " + getNasc() + ".";
allText+="\n";
allText+="Deaths : " + getMortes() + ".";
allText+="\n";
allTExt+="Total Population : " + getPopTotal() + ".";
view.setText(allText);
allText="";//reset the string
}
}, 1000);
}
}`
In your activity_main.xml inside yout TextView declaration add
<TextView ...
... <!--other params that you have set-->
android:id="#+id/textview_id"
... />
try this way me this help u
public class test extends Activity {
private TextView textView;
private int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
textView = (TextView)findViewById(R.id.text);
set();
}
private void set(){
final String text ="A n d r o i d P r o g r a m m i n g";
final String[] words = text.toString().split(" ");
final Handler handler = new Handler();
handler.post(new Runnable(){
#Override
public void run() {
textView.setText(""+words[i]);
i++;
if(i < words.length) {
handler.postDelayed(this, 1000);
}
}
});
}}
import this :
//
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
//
and use this for every one minute :
ScheduledExecutorService scheduleTaskExecut = Executors.newScheduledThreadPool(5);
// This run every one minute
scheduleTaskExecut.scheduleAtFixedRate(new Runnable() {
public void run() {
//in this Methos Update Your Text as You Need
UpdateYourText();
}
}, 0, 1, TimeUnit.MINUTES);
Related
I am having a problem with merging two activities in Android Studio. I am new to coding and I know this should be relatively simple but I am slowly learning, so bear with me.
Basically my starting activity was a sample app that came with the IOIO development board. I have modified this to work for my application. I also have a MAX31855 thermocouple amplifier that I have found code for and it is working perfect, the only problem is that all of the code is in a separate activity from my sample app activity. So both will not run at the same time on my simple one screen app. So now I am trying to merge the thermocouple amplifier code into the sample app code. How should I start going about this? I have attached the code for both activities below.
The code for the sample app:
package ioio.examples.simple;
import ioio.lib.api.AnalogInput;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import ioio.lib.api.SpiMaster;
import ioio.lib.api.SpiMaster.Rate;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;
import java.util.ArrayList;
import java.util.List;
public class IOIOSimpleApp extends IOIOActivity {
private TextView boost;
private TextView fuelpressure;
private TextView ioioStatusText;
private TextView internalText;
private TextView thermocoupleText;
private TextView faultsText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
enableUi(false);
}
class Looper extends BaseIOIOLooper {
private AnalogInput boost, fuelpressure;
#Override
public void setup() throws ConnectionLostException {
boost = ioio_.openAnalogInput(45);
fuelpressure = ioio_.openAnalogInput(42);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
setNumber1(38.314 * ((boost.getVoltage() - 0.27)));
setNumber2(38.314 * ((fuelpressure.getVoltage() - 0.27)));
Thread.sleep(200);
}
#Override
public void disconnected() {
enableUi(false);
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void enableUi(final boolean enable) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//seekBar_.setEnabled(enable);
//toggleButton_.setEnabled(enable);
}
});
}
private void setNumber1(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
boost.setText(str);
}
});
}
private void setNumber2(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
fuelpressure.setText(str);
}
});
}
}
And the code for the thermocouple amplifier:
package ioio.examples.simple;
import ioio.lib.api.SpiMaster;
import ioio.lib.api.SpiMaster.Rate;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import ioio.lib.api.AnalogInput;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends IOIOActivity {
protected static final float FAULT_DISPLAY_DURATION = 10; // seconds
private TextView ioioStatusText;
private TextView internalText;
private TextView thermocoupleText;
private TextView faultsText;
private TextView boost;
private TextView fuelpressure;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
}
#Override
protected IOIOLooper createIOIOLooper() {
int sdoPin = 1; // DO
int sdaPin = 29; // we do not use this pin but the IOIOLib requires we specify it, so we pick an unused pin
int sclPin = 2; // CLK
int csPin = 3; // CS
Rate rate = SpiMaster.Rate.RATE_31K;
final MAX31855 max31855 = new MAX31855(sdoPin, sdaPin, sclPin, csPin, rate);
max31855.setListener(new MAX31855.MAX31855Listener() {
private long faultTime;
#Override
public void onData(float internal, float thermocouple) {
updateTextView(internalText, "Internal = " + internal + " C");
updateTextView(thermocoupleText, thermocouple + " C");
float secondsSinceFault = (System.nanoTime() - faultTime) / 1000000000.0f;
if (secondsSinceFault > FAULT_DISPLAY_DURATION) {
updateTextView(faultsText, "Faults = ");
}
}
#Override
public void onFault(byte f) {
List<String> faults = new ArrayList<String>();
if ((f & MAX31855.FAULT_OPEN_CIRCUIT_BIT) == MAX31855.FAULT_OPEN_CIRCUIT_BIT)
faults.add("Open Circuit");
if ((f & MAX31855.FAULT_SHORT_TO_GND_BIT) == MAX31855.FAULT_SHORT_TO_GND_BIT)
faults.add("Short To GND");
if ((f & MAX31855.FAULT_SHORT_TO_VCC_BIT) == MAX31855.FAULT_SHORT_TO_VCC_BIT)
faults.add("Short To VCC");
boolean first = true;
String text = "Faults = ";
for (String fault : faults) {
if (!first)
text += ", ";
text += fault;
}
if (faults.size() > 0) {
faultTime = System.nanoTime();
}
updateTextView(faultsText, text);
}
});
return new DeviceLooper(max31855);
}
private void updateTextView(final TextView textView, final String text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(text);
}
});
}
/**
* This is the thread on which all the IOIO activity happens. It will be run
* every time the application is resumed and aborted when it is paused. The
* method setup() will be called right after a connection with the IOIO has
* been established (which might happen several times!). Then, loop() will
* be called repetitively until the IOIO gets disconnected.
*/
class DeviceLooper extends BaseIOIOLooper {
private IOIOLooper device;
public DeviceLooper(IOIOLooper device) {
this.device = device;
}
#Override
public void setup() throws ConnectionLostException, InterruptedException {
device.setup(ioio_);
updateTextView(ioioStatusText, "IOIO Connected");
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
device.loop();
}
#Override
public void disconnected() {
device.disconnected();
updateTextView(ioioStatusText, "IOIO Disconnected");
}
#Override
public void incompatible() {
updateTextView(ioioStatusText, "IOIO Incompatible");
}
}
}
I hope this makes sense and I have provided enough information. There is another separate activity for the MAX31855, but I assume this can be left untouched. Again, I am slowly learning how java and android studio works, I just can't seem to figure out how to merge these two activities without having a bunch of errors in the code. Any help is appreciated, thank you!
You need to consider three things.
1) main.xml Layout file in res->layout
2) AndroidManifest.xml in manifest folder
3) Single activity which include all codes.
All components should be initialized from a same activity (in your case MainActivity or IOIOSimpleApp).
Also remember to include all components (what you have initialized from activity) to the main.xml layout.
And try this
public class IOIOSimpleApp extends IOIOActivity {
protected static final float FAULT_DISPLAY_DURATION = 10; // seconds
private TextView boost;
private TextView fuelpressure;
private TextView ioioStatusText;
private TextView internalText;
private TextView thermocoupleText;
private TextView faultsText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
//components in main activity
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
enableUi(false);
}
class Looper extends BaseIOIOLooper {
private AnalogInput boost, fuelpressure;
#Override
public void setup() throws ConnectionLostException {
boost = ioio_.openAnalogInput(45);
fuelpressure = ioio_.openAnalogInput(42);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
setNumber1(38.314 * ((boost.getVoltage() - 0.27)));
setNumber2(38.314 * ((fuelpressure.getVoltage() - 0.27)));
Thread.sleep(200);
}
#Override
public void disconnected() {
enableUi(false);
}
}
#Override
protected IOIOLooper createIOIOLooper() {
int sdoPin = 1; // DO
int sdaPin = 29; // we do not use this pin but the IOIOLib requires we specify it, so we pick an unused pin
int sclPin = 2; // CLK
int csPin = 3; // CS
SpiMaster.Rate rate = SpiMaster.Rate.RATE_31K;
final MAX31855 max31855 = new MAX31855(sdoPin, sdaPin, sclPin, csPin, rate);
max31855.setListener(new MAX31855.MAX31855Listener() {
private long faultTime;
#Override
public void onData(float internal, float thermocouple) {
updateTextView(internalText, "Internal = " + internal + " C");
updateTextView(thermocoupleText, thermocouple + " C");
float secondsSinceFault = (System.nanoTime() - faultTime) / 1000000000.0f;
if (secondsSinceFault > FAULT_DISPLAY_DURATION) {
updateTextView(faultsText, "Faults = ");
}
}
#Override
public void onFault(byte f) {
List<String> faults = new ArrayList<String>();
if ((f & MAX31855.FAULT_OPEN_CIRCUIT_BIT) == MAX31855.FAULT_OPEN_CIRCUIT_BIT)
faults.add("Open Circuit");
if ((f & MAX31855.FAULT_SHORT_TO_GND_BIT) == MAX31855.FAULT_SHORT_TO_GND_BIT)
faults.add("Short To GND");
if ((f & MAX31855.FAULT_SHORT_TO_VCC_BIT) == MAX31855.FAULT_SHORT_TO_VCC_BIT)
faults.add("Short To VCC");
boolean first = true;
String text = "Faults = ";
for (String fault : faults) {
if (!first)
text += ", ";
text += fault;
}
if (faults.size() > 0) {
faultTime = System.nanoTime();
}
updateTextView(faultsText, text);
}
});
return new IOIOSimpleApp.DeviceLooper(max31855);
}
private void enableUi(final boolean enable) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//seekBar_.setEnabled(enable);
//toggleButton_.setEnabled(enable);
}
});
}
private void setNumber1(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
boost.setText(str);
}
});
}
private void setNumber2(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
fuelpressure.setText(str);
}
});
}
private void updateTextView(final TextView textView, final String text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(text);
}
});
}
/**
* This is the thread on which all the IOIO activity happens. It will be run
* every time the application is resumed and aborted when it is paused. The
* method setup() will be called right after a connection with the IOIO has
* been established (which might happen several times!). Then, loop() will
* be called repetitively until the IOIO gets disconnected.
*/
class DeviceLooper extends BaseIOIOLooper {
private IOIOLooper device;
public DeviceLooper(IOIOLooper device) {
this.device = device;
}
#Override
public void setup() throws ConnectionLostException, InterruptedException {
device.setup(ioio_);
updateTextView(ioioStatusText, "IOIO Connected");
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
device.loop();
}
#Override
public void disconnected() {
device.disconnected();
updateTextView(ioioStatusText, "IOIO Disconnected");
}
#Override
public void incompatible() {
updateTextView(ioioStatusText, "IOIO Incompatible");
}
} }
Hope this is work :)
I want make a Dice game, i have use a github project (https://github.com/dylanmtaylor/Simple-Dice).
The MainActivity is available here : https://github.com/dylanmtaylor/Simple-Dice/blob/master/src/com/dylantaylor/simpledice/RollDice.java
I want to get the value of the dice
Exemple :
If the first dice is 1 and the second is 6 we have a total of 7 i want make an action.
I have make a button who change a textview, this button try to get the number of the dices.
TextView hwTextView = (TextView)findViewById(R.id.textView8);
hwTextView.setText(String.valueOf(diceSum));
I have try to get the value "diceSum", "diceImages", "dice", "dice[roll[0]", "dice[roll[1]" but that didn't show a number.
How can i do try to get the value of the dice ?
My MainActivity
public class dices extends AppCompatActivity {
Button button;
private final int rollAnimations = 50;
private final int delayTime = 15;
private Resources res;
private final int[] diceImages = new int[] { R.drawable.d1, R.drawable.d2, R.drawable.d3, R.drawable.d4, R.drawable.d5, R.drawable.d6 };
private Drawable dice[] = new Drawable[6];
private final Random randomGen = new Random();
#SuppressWarnings("unused")
private int diceSum;
private int roll[] = new int[] { 6, 6 };
private ImageView die1;
private ImageView die2;
private LinearLayout diceContainer;
private SensorManager sensorMgr;
private Handler animationHandler;
private long lastUpdate = -1;
private float x, y, z;
private float last_x, last_y, last_z;
private boolean paused = false;
private static final int UPDATE_DELAY = 50;
private static final int SHAKE_THRESHOLD = 800;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
paused = false;
setContentView(R.layout.activity_dixit);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.setStatusBarColor(Color.parseColor("#2c3e50"));
}
View view = this.getWindow().getDecorView();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
button=(Button)findViewById(R.id.button_roll);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDice();
TextView hwTextView = (TextView)findViewById(R.id.textView8);
hwTextView.setText(String.valueOf(diceSum));
}
});
res = getResources();
for (int i = 0; i < 6; i++) {
dice[i] = res.getDrawable(diceImages[i]);
}
die1 = (ImageView) findViewById(R.id.die1);
die2 = (ImageView) findViewById(R.id.die2);
animationHandler = new Handler() {
public void handleMessage(Message msg) {
die1.setImageDrawable(dice[roll[0]]);
die2.setImageDrawable(dice[roll[1]]);
}
};
}
private void rollDice() {
if (paused) return;
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < rollAnimations; i++) {
doRoll();
}
}
}).start();
MediaPlayer mp = MediaPlayer.create(this, R.raw.roll);
try {
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
}
private void doRoll() { // only does a single roll
roll[0] = randomGen.nextInt(6);
roll[1] = randomGen.nextInt(6);
diceSum = roll[0] + roll[1] + 2; // 2 is added because the values of the rolls start with 0 not 1
synchronized (getLayoutInflater()) {
animationHandler.sendEmptyMessage(0);
}
try { // delay to alloy for smooth animation
Thread.sleep(delayTime);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
public void onResume() {
super.onResume();
paused = false;
}
public void onPause() {
super.onPause();
paused = true;
}
}
I didn't understand why your code didn't work. I myself making a very small games based on "Scarne's dice game(pig)" and myself facing the challenge of retrieving the value of dice rolled. Mind, I am just using one die. This is what I did:
int userScore;
private int[] diceArray = {R.drawable.d1, R.drawable.d2, R.drawable.d3,
R.drawable.d4,R.drawable.d5,R.drawable.d6};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onRollBtnClicked() {
ImageView diceFace = (ImageView) findViewById(R.id.diceFaceImageView);
userScore = randomIntegerGenerator(1,6); // this is what you need
diceFace.setImageResource(diceArray[userScore]);
}
// function to return random integer from min to max
public int randomIntegerGenerator(int min, int max) {
return random.nextInt((max - min) + 1) + min;
}
I am storing my rolled die value in userScore. You can use the similar approach.
Hi there i've been constructing this code for a week but i still cant get it to work. It has no errors but when i run it on the AVD it terminates suddenly.
package com.tryout.sample;
import java.util.Random;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity implements View.OnClickListener{
Random number = new Random();
int Low = 1;
int High = 13;
int RandomNumber = number.nextInt(High-Low) + Low;
int current = 0;
int points=0;
final Integer[] cardid = { R.drawable.card1,
R.drawable.card10,
R.drawable.card11,
R.drawable.card12,
R.drawable.card13,
R.drawable.card2,
R.drawable.card3,
R.drawable.card4,
R.drawable.card5,
R.drawable.card6,
R.drawable.card7,
R.drawable.card8,
R.drawable.card9,
};
ImageView pic2 = (ImageView) findViewById(R.id.imageView1);
final TextView score = (TextView) findViewById(R.id.textView2);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView score = (TextView) findViewById(R.id.textView2);
Button high = (Button) findViewById(R.id.button1);
Button low = (Button) findViewById(R.id.button2);
final ImageView pic = (ImageView) findViewById(R.id.imageView1);
low.setOnClickListener(new view.OnClickListener() {
public void onClick(View v) {
int resource = cardid[RandomNumber];
if(current < RandomNumber){
points = points + 1;
score.setText(points);
pic.setImageResource(resource);
}else{
score.setText("Game Over");
}
}
});
high.setOnClickListener(new View.OnClickListener() {
public void higher(View v) {
int resource = cardid[RandomNumber];
if(current > RandomNumber){
points = points + 1;
score.setText(points);
pic.setImageResource(resource);
}else{
score.setText("Game Over");
}
}
});
int resource = cardid[RandomNumber];
pic.setImageResource(resource);
current = RandomNumber;
}
}
I cant figure out where my problem is, kindly check out my code. THanks for any help
put this:
ImageView pic2 = (ImageView) findViewById(R.id.imageView1);
final TextView score = (TextView) findViewById(R.id.textView2);
in you onCreate method after the call setContentView(R.layout.activity_main);.
How should R.id.imageView1 assigned if the content is not specified like in your case?
ImageView pic2;
TextView score;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pic2 = (ImageView) findViewById(R.id.imageView1);
score = (TextView) findViewById(R.id.textView2);
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
public class minigame_cardpairing extends Activity implements View.OnClickListener {
private static final int TOTAL_CARD_NUM = 16;
private int[] cardId = {R.id.card01, R.id.card02, R.id.card03, R.id.card04, R.id.card05, R.id.card06, R.id.card07, R.id.card08,
R.id.card09, R.id.card10, R.id.card11, R.id.card12, R.id.card13, R.id.card14, R.id.card15, R.id.card16};
private Card[] cardArray = new Card[TOTAL_CARD_NUM];
private int CLICK_CNT = 0;
private Card first, second;
private int SUCCESS_CNT = 0;
private boolean INPLAY = false;
//----------- Activity widget -----------//
private Button start;
//-----------------------------------//
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.minigame_cardpairing);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
for(int i=0; i<TOTAL_CARD_NUM; i++) {
cardArray[i] = new Card(i/2);
findViewById(cardId[i]).setOnClickListener(this);
cardArray[i].card = (ImageButton) findViewById(cardId[i]); // Card assignment
cardArray[i].onBack();
}
start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startGame();
//start.setBackgroundDrawable(background);
}
});
findViewById(R.id.exit).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
setResult(RESULT_OK);
finish();
}
});
} // end of onCreate
protected void startDialog() {
AlertDialog.Builder alt1 = new AlertDialog.Builder(this);
alt1.setMessage("The match-card game. Please remember to flip the cards two by two card hand is a pair Hit. Hit all pairs are completed.")
.setCancelable(false)
.setPositiveButton("close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alt2 = alt1.create();
alt2.setTitle("Game Description");
alt2.show();
}
protected void clearDialog() {
AlertDialog.Builder alt1 = new AlertDialog.Builder(this);
alt1.setMessage("It fits all the cards in pairs. Congratulations.")
.setCancelable(false)
.setPositiveButton("close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alt2 = alt1.create();
alt2.setTitle("Match-complete");
alt2.show();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
startDialog();
}
public void onClick(View v) {
if (INPLAY) {
switch (CLICK_CNT) {
case 0:
for (int i=0; i<TOTAL_CARD_NUM; i++) {
if (cardArray[i].card == (ImageButton) v) {
first = cardArray[i];
break;
}
}
if (first.isBack) {
first.onFront();
CLICK_CNT = 1;
}
break;
case 1:
for (int i=0; i<TOTAL_CARD_NUM; i++) {
if (cardArray[i].card == (ImageButton) v) {
second = cardArray[i];
break;
}
}
if (second.isBack) {
second.onFront();
if (first.value == second.value) {
SUCCESS_CNT++;
Log.v("SUCCESS_CNT", "" + SUCCESS_CNT);
if (SUCCESS_CNT == TOTAL_CARD_NUM/2) {
clearDialog();
}
}
else {
Timer t = new Timer(0);
t.start();
}
CLICK_CNT = 0;
}
break;
}
}
}
void startGame() {
int[] random = new int[TOTAL_CARD_NUM];
int x;
for (int i=0; i<TOTAL_CARD_NUM; i++) {
if (!cardArray[i].isBack)
cardArray[i].onBack();
}
boolean dup;
for (int i=0; i<TOTAL_CARD_NUM; i++) {
while(true) {
dup = false;
x = (int) (Math.random() * TOTAL_CARD_NUM);
for (int j=0; j<i; j++) {
if (random[j] == x) {
dup = true;
break;
}
}
if (!dup) break;
}
random[i] = x;
}
start.setClickable(false);
for (int i=0; i<TOTAL_CARD_NUM; i++) {
cardArray[i].card = (ImageButton) findViewById(cardId[random[i]]);
cardArray[i].onFront();
}
Log.v("timer", "start");
Timer t = new Timer(1);
//flag = false;
t.start();
/*
while(true) {
if (flag) break;
//Log.v("flag", "" + flag);
}
Log.v("timer", "end");
*/
SUCCESS_CNT = 0;
CLICK_CNT = 0;
INPLAY = true;
}
class Timer extends Thread {
int kind;
Timer (int kind) {
super();
this.kind = kind;
}
#Override
public void run() {
INPLAY = false;
// TODO Auto-generated method stub
try {
if (kind == 0) {
Thread.sleep(1000);
mHandler.sendEmptyMessage(0);
}
else if (kind == 1) {
Thread.sleep(3000);
mHandler.sendEmptyMessage(1);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
INPLAY = true;
}
}
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
first.onBack();
second.onBack();
first.isBack = true;
second.isBack = true;
}
else if (msg.what == 1) {
//flag = true;
for (int i=0; i<TOTAL_CARD_NUM; i++) {
cardArray[i].onBack();
}
start.setClickable(true);
}
}
};
}
class Card { // start of Card class
private final static int backImageID = R.drawable.cardback;
private final static int[] frontImageID = {R.drawable.card1, R.drawable.card2,
R.drawable.card3, R.drawable.card4,
R.drawable.card5, R.drawable.card6,
R.drawable.card7, R.drawable.card8};
int value;
boolean isBack;
ImageButton card;
Card(int value) {
this.value = value;
}
public void onBack() {
if (!isBack) {
card.setBackgroundResource(backImageID);
isBack = true;
}
}
public void flip() {
if (!isBack) {
card.setBackgroundResource(backImageID);
isBack = true;
}
else {
card.setBackgroundResource(frontImageID[value]);
isBack = false;
}
}
public void onFront() {
if (isBack) {
card.setBackgroundResource(frontImageID[value]);
isBack = false;
}
}
} // end of Card class
I'm making a minesweeper game. I'm placing all of the buttons I use for the game in a GridLayout.
The buttons eventually push the layout to be bigger than the size of the screen, so I placed the layout in a HorizontalScrollView and a ScrollView. However, when the game ends, I want to zoom out the layout so I can see all of the buttons on screen.
I've posted the relevant files, although the most important content is fragment_grid.xml (the xml file containing the GridLayout) and GridFragment::gameOver() (where I want to put the zoom-out code)
fragment_grid.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/grid"
android:columnCount="10"
android:rowCount="10">
</GridLayout>
</HorizontalScrollView>
</ScrollView>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:clickable="true"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</RelativeLayout>
GridFragment.java:
public class GridFragment extends Fragment {
GridLayout gridLayout;
public enum GameState{READY, PLAYING, WIN, LOSE}
GameState gameState;
public GridFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
gameState = GameState.READY;
View view = inflater.inflate(R.layout.fragment_grid, container, false);
gridLayout = (GridLayout)view.findViewById(R.id.grid);
MButton[] buttons = generateGrid(100,25);
for(MButton mButton:buttons){
gridLayout.addView(mButton);
}
return view;
}
public MButton[] generateGrid(int gridSize, int numMines){
Log.d("gridSize",""+gridSize);
Log.d("numMines",""+numMines);
ArrayList<Integer> array = new ArrayList<Integer>();
for (int i = 0; i < gridSize; i++) {
array.add(new Integer(i));
}
Log.d("unsorted",array.toString());
Collections.shuffle(array,new Random(System.currentTimeMillis()));
MButton[] mButtons = new MButton[gridSize];
MButton mButton;
String numList = array.toString();
Log.d("arraySize",""+array.size());
Log.d("array",numList);
for (int i = 0; i < gridSize; i++) {
int x = array.get(i);
mButton = new MButton(getActivity(),i, numMines > x);
mButtons[i] = mButton;
}
return generateMineCount(mButtons);
}
private MButton[] generateMineCount(MButton[] mButtons){
int rows = gridLayout.getRowCount();
int columns = gridLayout.getColumnCount();
for (int i = 0; i < mButtons.length; i++) {
if((i/columns) > 0){if(mButtons[i-columns].isMine()){mButtons[i].addAdjacentMines();}}
if((i/columns) < rows-1){if(mButtons[i+columns].isMine()){mButtons[i].addAdjacentMines();}}
if((i%rows) > 0){if(mButtons[i-1].isMine()){mButtons[i].addAdjacentMines();}}
if((i%rows) < columns-1){if(mButtons[i+1].isMine()){mButtons[i].addAdjacentMines();}}
if( ((i/columns) > 0)&&((i%rows) > 0) ){if(mButtons[i-columns-1].isMine()){mButtons[i].addAdjacentMines();}}
if( ((i/columns) < rows-1)&&((i%rows) > 0) ){if(mButtons[i+columns-1].isMine()){mButtons[i].addAdjacentMines();}}
if( ((i/columns) > 0)&&((i%rows) < columns-1) ){if(mButtons[i-columns+1].isMine()){mButtons[i].addAdjacentMines();}}
if( ((i/columns) < rows-1)&&((i%rows) < columns-1) ){if(mButtons[i+columns+1].isMine()){mButtons[i].addAdjacentMines();}}
if(!mButtons[i].isMine() && mButtons[i].getAdjacentMines() > 0){mButtons[i].displayMines();}
}
return mButtons;
}
public void startGame(){
gameState = GameState.PLAYING;
}
public void gameOver(){
gameState = GameState.LOSE;
for (int i = 0; i < gridLayout.getChildCount(); i++) {
MButton mb = (MButton)gridLayout.getChildAt(i);
mb.setOnTouchListener(null);
//insert zoom-out layout code here
}
gridLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
}
MButton.java:
public class MButton extends Button {
public enum State{NORMAL, OPENED, FLAGGED, UNKNOWN}
State state;
boolean longPress;
long startTime = 0;
int num;
boolean mine;
final float scale = getContext().getResources().getDisplayMetrics().density;
int adjacentMines = 0;
MainActivity mainActivity = (MainActivity)getContext();
GridFragment gridFragment = (GridFragment)mainActivity.getFragmentManager().findFragmentByTag("gridFragment");
ImageButton startButton = (ImageButton)(mainActivity.getActionBar()).getCustomView().findViewById(R.id.actionBarLogo);
static Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long milliseconds = System.currentTimeMillis() - startTime;
longPress = false;
if(milliseconds >= 1500) {
longPressTile();
timerHandler.removeCallbacks(timerRunnable);
}
else
timerHandler.postDelayed(this, 0);
}
};
public MButton(Context context, int i, boolean m) {
super(context);
create(i, m);
}
public MButton(Context context, AttributeSet attrs, int i, boolean m) {
super(context, attrs);
create(i, m);
}
public MButton(Context context, AttributeSet attrs, int defStyleAttr, int i, boolean m) {
super(context, attrs, defStyleAttr);
create(i, m);
}
private void longPressTile(){
longPress = true;
setBackgroundResource(R.drawable.tile);
startButton.setImageResource(R.drawable.smiley);
if(state == State.FLAGGED || state == State.UNKNOWN){
state = State.NORMAL;
setText("");
}
else if(state == State.NORMAL){
state = State.FLAGGED;
setText("F");
}
}
private boolean isInGrayArea(float xCoord, float yCoord){
int xValue = (int) ((xCoord/scale)+0.5);
int yValue = (int) ((yCoord/scale)+0.5);
Log.d("button"+num,"("+xValue+","+yValue+")");
Log.d("size","("+Integer.toString(getWidth())+","+Integer.toString(getHeight())+")");
return (xValue >= 5)&&(xValue < 45)&&(yValue >= 5)&&(yValue < 45);
}
public void addAdjacentMines(){
adjacentMines++;
}
public boolean isMine(){
return mine;
}
public void displayMines(){
if(mine)
setText("M");
else if(hasAdjacentMines())
setText(""+adjacentMines);
else
setText("");
}
public int getAdjacentMines(){
return adjacentMines;
}
public boolean hasAdjacentMines(){ return getAdjacentMines() > 0;}
private void openAdjacentButtons(){
GridLayout gridLayout = gridFragment.gridLayout;
int rows = gridLayout.getRowCount();
int columns = gridLayout.getColumnCount();
if((num/columns) > 0){((MButton)gridLayout.getChildAt(num-columns)).revealButton();}
if((num/columns) < rows-1){((MButton)gridLayout.getChildAt(num+columns)).revealButton();}
if((num%rows) > 0){((MButton)gridLayout.getChildAt(num-1)).revealButton();}
if((num%rows) < columns-1){((MButton)gridLayout.getChildAt(num+1)).revealButton();}//
if( ((num/columns) > 0)&&((num%rows) > 0) ){((MButton)gridLayout.getChildAt(num-columns-1)).revealButton();}
if( ((num/columns) < rows-1)&&((num%rows) > 0) ){((MButton)gridLayout.getChildAt(num+columns-1)).revealButton();}
if( ((num/columns) > 0)&&((num%rows) < columns-1) ){((MButton)gridLayout.getChildAt(num-columns+1)).revealButton();}
if( ((num/columns) < rows-1)&&((num%rows) < columns-1) ){((MButton)gridLayout.getChildAt(num+columns+1)).revealButton();}
}
public void revealButton() {
if (state != State.OPENED){
state = State.OPENED;
displayMines();
if (!isMine() && !hasAdjacentMines())
openAdjacentButtons();
else if(isMine()){
startButton.setImageResource(R.drawable.smiley3);
gridFragment.gameOver();
}
setBackgroundResource(R.drawable.tile3);
}
}
private void create(int i, boolean m){
state = State.NORMAL;
num = i;
mine = m;
setBackgroundResource(R.drawable.tile);
setLayoutParams(new LinearLayout.LayoutParams(150,150));
if(mine){
setText("m");
}
this.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent me) {
if(isInGrayArea(me.getX(), me.getY())){
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN: {
if (state != State.OPENED) {
if(gridFragment.gameState == GridFragment.GameState.READY)
gridFragment.startGame();
startTime = System.currentTimeMillis();
v.setBackgroundResource(R.drawable.tile2);
startButton.setImageResource(R.drawable.smiley2);
timerHandler.postDelayed(timerRunnable, 0);
}
return true;
}
case MotionEvent.ACTION_UP: {
if (!longPress) {
startButton.setImageResource(R.drawable.smiley);
switch(state){
case NORMAL:{
revealButton();
break;
}
case UNKNOWN:{
state = State.UNKNOWN;
v.setBackgroundResource(R.drawable.tile);
setText("?");
break;
}
case FLAGGED:{
state = State.FLAGGED;
v.setBackgroundResource(R.drawable.tile);
setText("F");
}
}
}
timerHandler.removeCallbacks(timerRunnable);
return true;
}
}
}
return false;
}
});
}
}
MainActivity.java
public class MainActivity extends Activity {
private boolean mInit = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setCustomView(R.layout.actionbar);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/digital-7.ttf");
TextView myTextView = (TextView)findViewById(R.id.textView1);
TextView myTopTextView = (TextView)findViewById(R.id.topTextView1);
myTextView.setTypeface(myTypeface);
myTopTextView.setTypeface(myTypeface);
if (findViewById(R.id.fragment_container) != null){
if (savedInstanceState != null) {
return;
}
}
}
private void initial(){
GridFragment gFragment = new GridFragment();
gFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(R.id.fragment_container, gFragment,"gridFragment").commit();
}
#Override
protected void onStart() {
if (!mInit) {
mInit = true;
initial();
}
super.onStart();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
P.S. Happy New Year's!
i guess this would help: Android - zoom in/out RelativeLayout with spread/pinch
you can applay the same implementation for gridLayout good luck :) and Happy new year
I know its been 6 months I spent hours trying to make this work.
This class should work for any view or viewgroup. Just extend whatever view or viewgroup needs to zoom.
https://github.com/Xjasz/AndroidZoomableViewGroup
I have set up a button with an onClick method called ButtonRoll which randomly generates a number from 1-100 then display the output below the button in a text view. This works fine but what I would like to move onto is to be able to cycle through 20 numbers being generated. I have tried the following the but it will only display the last number being generated. I am guessing this is because the UI isn't being updated untill the last number is generated.
public void ButtonRoll(View view) {
int n;
Random rand = new Random();
TextView textRoll = (TextView) findViewById(R.id.textview_roll);
for (int i=0; i<20; i++){
try {
Thread.sleep(200);
n = rand.nextInt(100) + 1;
String roll = String.valueOf(n);
textRoll.setText("Random number is " + roll);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Would I have to use a Handler at all? Or is there a simpler solution?
Thanks for your time.
Give this a try.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button android:id="#+id/button_roll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="Roll"/>
<TextView android:id="#+id/textview_roll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/button_roll" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity implements OnClickListener
{
private class Roller implements Runnable
{
private int numTimes;
private long delayMillis;
public Roller(int numTimes, long delayMillis)
{
this.numTimes = numTimes;
this.delayMillis = delayMillis;
}
#Override
public void run()
{
if (textRoll != null)
{
int n = rand.nextInt(100) + 1;
String roll = String.valueOf(n);
textRoll.setText("Random number is " + roll);
numTimes--;
if (numTimes > 0)
{
textRoll.postDelayed(this, delayMillis);
}
}
}
}
private TextView textRoll;
private Random rand = new Random();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_roll).setOnClickListener(this);
textRoll = (TextView)findViewById(R.id.textview_roll);
}
#Override
public void onDestroy()
{
findViewById(R.id.button_roll).setOnClickListener(null);
textRoll = null;
super.onDestroy();
}
#Override
public void onClick(View v)
{
int id = v.getId();
if (id == R.id.button_roll)
{
findViewById(R.id.textview_roll).post(new Roller(20, 100));
}
}
}
you can use handler concept:
There are several ways to update your UI and modify a View such as a TextView from outside of the UI Thread. A Handler is just one method.
Here is an example that allows a single Handler respond to various types of requests.
private final static int DO_UPDATE_TEXT = 0;
private final static int DO_THAT = 1;
private final Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
final int what = msg.what;
switch(what) {
case DO_UPDATE_TEXT: doUpdate(); break;
case DO_THAT: doThat(); break;
}
}
};
Update the UI in one of your functions, which is now on the UI Thread:
private void doUpdate() {
myTextView.setText("updating..");
}
in your asynchronous task, send a message to the Handler. There are several ways to do it. This may be the simplest:
myHandler.sendEmptyMessage(DO_UPDATE_TEXT);
After noticing the .post method as mentioned beforehand, I had a play and came up with this version which does the same. Can you see any reason why is would unadvisable to run it this way?
public void ButtonRoll(View view) {
new Thread(new Runnable() {
#Override
public void run() {
for(int i = 0; i<50;i++) {
try {
Thread.sleep(50);
final TextView textRoll = (TextView) findViewById(R.id.textview_roll);
int n;
Random rand = new Random();
n = rand.nextInt(100) + 1;
final String roll = String.valueOf(n);
textRoll.post(new Runnable() {
#Override
public void run() {
textRoll.setText("Random number is " + roll);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}