Dynamic background based on a timer (linear layout), how to? - android

Hi I'm kind of beginner to android OS programming, and I got stuck with a problem, I cant figure out how to do a dynamic background, based on timers (say each 10 seconds a background changes to a different one) I have some code but it comes up with error, here's a sample:
private static final long GET_DATA_INTERVAL = 10000;
int images[] = {R.drawable.smothie1,R.drawable.omletherb1};
int index = 0;
ImageView img;
Handler hand = new Handler();
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
LinearLayout layout= (LinearLayout)findViewById(R.id.LinearView1);
hand.postDelayed(run, GET_DATA_INTERVAL);
}
Runnable run = new Runnable() {
public void run() {
layout.setBackgroundResource(LinearView1).getDrawable(images[index++]);
if (index == images.length)
index = 0;
hand.postDelayed(run, GET_DATA_INTERVAL);
Any help would be greatly apprieciated :D thanks
EDIT: The errors I get are on this line:
layout.setBackgroundResource(LinearView1).getDrawable(images[index++]);
It says that:
-layout cannot be resolved
-the method getDrawable(int) is undefined for the type Object
This error:
layout.setBackgroundResource(LinearView1).getDrawable(images[index++]);
It says that:
-layout cannot be resolved
-the method getDrawable(int) is undefined for the type Object
Please help :)

I have finally worked it out, after removing a few errors I have came up with this (and its working) :
public class CookBookActivity extends Activity {
/** Called when the activity is first created. */
private static final long GET_DATA_INTERVAL = 1000;
int images[] = {R.drawable.omletherb1,R.drawable.smothie1};
int index = 0;
LinearLayout img;
Handler hand = new Handler();
private LinearLayout layout;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
layout = (LinearLayout)findViewById(R.layout.main);
hand.postDelayed(run, GET_DATA_INTERVAL);
Typeface tf2 = Typeface.createFromAsset(getAssets(),
"fonts/BPreplay.otf");
TextView tv2 = (TextView) findViewById(R.id.textView2);
tv2.setTypeface(tf2);
Typeface tf = Typeface.createFromAsset(getAssets(),
"fonts/BPreplay.otf");
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setTypeface(tf);
Button mainNext = (Button) findViewById(R.id.nextScreen1);
mainNext.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent();
i.setClassName("com.unKnown.cookbook", "com.unKnown.cookbook.screen1");
startActivity(i);
}
});
}
Runnable run = new Runnable() {
public void run() {
layout.setBackgroundDrawable(getDrawable(index++));
if (index == images.length)
index = 0;
hand.postDelayed(run, GET_DATA_INTERVAL);
}
};
protected Drawable getDrawable(int i) {
// TODO Auto-generated method stub
return getResources().getDrawable(images[i%2]);
}
}

Related

Runtime Error, by starting the Application [duplicate]

This question already has answers here:
How to set Id of dynamic created layout?
(10 answers)
Closed 5 years ago.
I have written a small app in Android Studio. If I start the app in the emulator, then I get an exception. The application simply stops.
The source code looks as follows:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private int points, round, countdown;
private static final int FROG_ID = 212121;
private Random rnd = new Random();
private Handler handler = new Handler();
private Runnable runnable = new Runnable(){
#Override
public void run(){
countdown();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//newGame();
showStartFragment();
}
private void newGame(){
points = 0;
round = 1;
initRound();
}
private void initRound(){
countdown = 10;
ViewGroup container = (ViewGroup) findViewById(R.id.container);
container.removeAllViews();
WimmelView wv = new WimmelView(this);
container.addView(wv, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
wv.setImageCount(5*(10+round));
ImageView frog = new ImageView(this);
frog.setId(FROG_ID);
frog.setImageResource(R.drawable.frog1);
frog.setScaleType(ImageView.ScaleType.CENTER);
float scale = getResources().getDisplayMetrics().density;
FrameLayout.LayoutParams lp= new FrameLayout.LayoutParams(Math.round(64*scale),Math.round(61*scale));
lp.leftMargin = rnd.nextInt(container.getWidth()-64);
lp.topMargin = rnd.nextInt(container.getHeight()-61);
lp.gravity = Gravity.TOP + Gravity.START;
frog.setOnClickListener(this);
container.addView(frog, lp);
handler.postDelayed(runnable, 1000-round*50);
update();
}
private void fillTextView(int id, String text){
TextView tv = (TextView) findViewById(id);
tv.setText(text);
}
private void update(){
fillTextView(R.id.points, Integer.toString(points));
fillTextView(R.id.round, Integer.toString(round));
fillTextView(R.id.countdown,
Integer.toString(countdown*1000));
}
private void showStartFragment(){
ViewGroup container = (ViewGroup) findViewById(R.id.container);
container.removeAllViews();
container.addView(
getLayoutInflater().
inflate(R.layout.fragment_start, null));
container.findViewById(R.id.start).setOnClickListener(this);
}
private void showGameOverFragment(){
ViewGroup container = (ViewGroup) findViewById(R.id.container);
container.addView(
getLayoutInflater().
inflate(R.layout.fragment_gameover, null));
container.findViewById(play_again).setOnClickListener(this);
}
#Override
public void onClick(View view) {
if(view.getId()==R.id.start){
startGame();
}else if(view.getId()==R.id.play_again){
showStartFragment();
}else if(view.getId()==FROG_ID){
handler.removeCallbacks(runnable);
Toast.makeText(this,R.string.kissed, Toast.LENGTH_SHORT).show();
//showToast(R.string.kissed);
points += countdown*1000;
round++;
}
initRound();
}
private void startGame() {
newGame();
}
private void countdown(){
countdown--;
update();
if(countdown<=0){
//frog.setOnClickListener(null);
showGameOverFragment();
}else {
handler.postDelayed(runnable, 1000-round*50);
}
}
#Override
protected void onPause(){
super.onPause();
handler.removeCallbacks(runnable);
}
}
At the beginning I came so far that I could at least press on start, now I am not at all more in the application pure ...
I have tried to googlen what it could be, but I have not succeeded in doing so. I also get a error message at the point frog.setId (FROG_ID).
In addition, I have yet another class, which implements images
public class WimmelView extends View {
private Random rnd;
private long randomSeed = 1;
private int imageCount;
private Paint paint = new Paint();
private static final int[]
images = { R.drawable.frog2,
R.drawable.frog3,R.drawable.frog4,
R.drawable.frog5,R.drawable.frog6};
public void setImageCount(int imageCount){
this.imageCount = imageCount;
randomSeed = System.currentTimeMillis();
invalidate();
}
public WimmelView(Context context){
super(context);
paint.setAntiAlias(true);
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
rnd = new Random(randomSeed);
for(int image:images){
Bitmap bitmap =
BitmapFactory.decodeResource(getResources(),image);
for(int i=0; i<imageCount/images.length; i++){
float left = (float) (rnd.nextFloat()
*(getWidth()-bitmap.getWidth()));
float top = (float) (rnd.nextFloat()
*(getWidth()-bitmap.getWidth()));
canvas.drawBitmap(bitmap,left,top,paint);
}
bitmap.recycle();
}
}
}
I hope someone sees the error and can help me ...
Your error is that the Content view is removing all children from the screen including the textviews of the score and points that you are trying to use. I just helped you move to fragments offline and ensured you were good to go. Goodluck.
You can use this,
<item name="frog_id" type="id"/>
This give you unique value.
You add this in your ids.xml. and change your code
...
frog.setId(R.id.frog_id);
...
else if(view.getId()==R.id.frog_id)
Try this
This is related to setting the view id. You can't set the id with the following:
private static final int FROG_ID = 212121;
...
frog.setId(FROG_ID);
You need to define an id in res/values/ids.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="your_view_id" type="id"/>
</resources>
But this will against the purpose of creating a dynamic view.
Instead, you can use View.generateViewId for the id instead. But please remember that this method only work from API version 17. Here the excerpt:
int generateViewId ()
Generate a value suitable for use in setId(int). This value will not
collide with ID values generated at build time by aapt for R.id.

App crashing at the end of array

My app is crashing at the end of the array in bluestacks. I have no idea why.
When I click the next button at the end of the array, the app crashes. I also tested it on my phone, same result. The rest of the app functions as intended.
From what I know "i %= image_elements.length;" is supposed to be the function that loops the array.
I am pretty sure this is where the crash is coming from.
i++;
element.setImageResource(image_elements[i]);
name.setImageResource(image_names[i]);
i %= image_elements.length;
Full code below
public class Practice extends MainMenuActivity {
int i = 0;
final int[] image_elements = {
R.drawable.spr_elements_0,
R.drawable.spr_elements_1,
[...]
R.drawable.spr_elements_86,
R.drawable.spr_elements_87,
};
final int[] image_names = {
R.drawable.spr_name_0,
R.drawable.spr_name_1,
[...]
R.drawable.spr_name_86,
R.drawable.spr_name_87,
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.practice);
final ImageView element = (ImageView) findViewById(R.id.element);
final ImageView name = (ImageView) findViewById(R.id.name);
Button nextButton = (Button) findViewById(R.id.buttonNext);
nextButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
i++;
element.setImageResource(image_elements[i]);
name.setImageResource(image_names[i]);
i %= image_elements.length;
}
});
}
public void backButton(View view) {
Intent z = new Intent(this, MainMenuActivity.class);
startActivity(z);
}
}
You'll need to rearrange your code from this:
i++;
element.setImageResource(image_elements[i]);
name.setImageResource(image_names[i]);
i %= image_elements.length;
to this:
i++;
i %= image_elements.length;
element.setImageResource(image_elements[i]);
name.setImageResource(image_names[i]);
What happens otherwise is that the index is incremented beyond the boundaries of the array, and that is corrected afterwards with the modulus operator. You'll need to the the correction before you use the index.
i %= image_elements.length in this particular case, is essentially the same as
if( i == image_elements.length ) {
i = 0;
}
Arrays indices go from 0 to length-1.
You could get rid of the arrays entirely by looking up the resources by name, such as this:
final static int MAX_ELEMENTS = 88; // this includes 0..87
private int index = 0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.practice);
final ImageView element = (ImageView) findViewById(R.id.element);
final ImageView name = (ImageView) findViewById(R.id.name);
final Resources res = this.getResources();
final String pkgName = this.getPackageName();
Button nextButton = (Button) findViewById(R.id.buttonNext);
nextButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final int imgId = res.getIdentifier( "spr_elements_" + index, "drawable", pkgName );
final int nameId = res.getIdentifier( "spr_name_" + index, "drawable", pkgName );
element.setImageResource( imgId );
name.setImageResource( nameId );
index = (index+1) % MAX_ELEMENTS;
}
});
}

Using Text Only Once Through Random Method

I am new to Android. I am showing Text in the TextView on Button click Randomly. On 1st Textview the Heading and on 2nd the explaination of that heading. I am able to show the Heading and Explaination Randomly and now I want if the Text is shown once should not be shown again means it will be removed. This is the point where I stuck. I am not able to remove the texts. Any help will be appreciated. I am posting my code here.
MainActivity.java
TextView text_heading,text_explain;
Button click;
Random random;
Integer [] array_heading ,array_explain ;
Integer int_text;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_heading = (TextView) findViewById(R.id.text_heading);
text_explain = (TextView) findViewById(R.id.text_explain);
click = (Button) findViewById(R.id.click);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
text_heading.setText(array_heading.get(int_text)); //getting error
text_explain(array_explain.get(int_text)); //getting error
array_heading.remove(int_text); //getting error
array_explain.remove(int_text); //getting error
}
});
random = new Random();
array_heading = new Integer []{R.string.source_text1, R.string.source_text2, R.string.source_text3,
R.string.source_text6, R.string.source_text5, R.string.source_text4, R.string.source_text7,
R.string.source_text8, R.string.source_text9};
array_explain = new Integer []{R.string.source_text1_explain, R.string.source_text2_explain,
R.string.source_text3_explain,
R.string.source_text4_explain, R.string.source_text5_explain, R.string.source_text6_explain,
R.string.source_text7_explain,
R.string.source_text8_explain, R.string.source_text9_explain};
ArrayList<Integer> array_headingList = new ArrayList<Integer>(Arrays.asList(array_heading));
ArrayList<Integer>array_explainList = new ArrayList<Integer>(Arrays.asList(array_explain));
int_text = random.nextInt(array_headingList.size() - 1);
}
}
I am not able to remove the texts. Any help will be appreciated. I am
posting my code here.
To clean the content of the TextView you could pass null to setText. E.g
text_heading.setText(null);
If you want to change the content every time you click on the button, you have to move
int_text = random.nextInt(array_heading.length);
your onClick callback,
You should be aware of the fact that next int returns an int between [0, n). array_heading.length -1 is necessary only if you want to exclude R.string.source_text9_explain from the possible texts you want to show. Keep also in mind that if array_heading contains more items than array_explain you could get ArrayIndexOutBoundException
I would keep the strings together in an object:
public class Item {
private final int textId;
private final int textExplanationId;
public class Item(int textId, int textExplanationId){
this.textId = textId;
this.textExplanationId = textExplanationId;
}
public int getTextId(){return textId;}
public int getTextExplanationId(){return textExplanationId;}
}
Then I would store those in an ArrayList:
List<Item> items = new ArrayList<Item>(new Item[]{
new Item(R.string.source_text1, R.string.source_text1_explain),
new Item(R.string.source_text2, R.string.source_text2_explain),
//etc
});
Then I would shuffle that array once:
Collections.shuffle(items);
And read from it in order:
Item current = items.get(currentIndex++);
text_heading.setText(current.getTextId());
text_explain.setText(current.getTextExplanationId());
TextView text_heading,text_explain;
Button click;
Random random;
Integer [] array_heading ,array_explain ;
Integer int_text;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_heading = (TextView) findViewById(R.id.text_heading);
text_explain = (TextView) findViewById(R.id.text_explain);
click = (Button) findViewById(R.id.click);
random = new Random();
array_heading = new Integer []{R.string.source_text1, R.string.source_text2, R.string.source_text3,
R.string.source_text6, R.string.source_text5, R.string.source_text4, R.string.source_text7,
R.string.source_text8, R.string.source_text9};
array_explain = new Integer []{R.string.source_text1_explain, R.string.source_text2_explain,
R.string.source_text3_explain,
R.string.source_text4_explain, R.string.source_text5_explain, R.string.source_text6_explain,
R.string.source_text7_explain,
R.string.source_text8_explain, R.string.source_text9_explain};
ArrayList<Integer> array_headingList = new ArrayList<Integer>(Arrays.asList(array_heading));
ArrayList<Integer> array_explainList = new ArrayList<Integer>(Arrays.asList(array_explain));
int_text = random.nextInt(array_headingList.size() - 1);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
text_heading.setText(array_headingList.get(int_text)); //getting error
text_explain.setText(array_explainList.get(int_text)); //getting error
array_headingList.remove(int_text); //getting error
array_explainList.remove(int_text); //getting error
}
});
}
}
You must use ArrayList for it.
ArrayList<Integer> heading = Arrays.asList(array_heading);
ArrayList<Integer> explain = Arrays.asList(array_explain);
Now set text from this arraylists. And when its set once remove it from the arraylist so it cannot be shown again.
Use like this
random = new Random();
array_heading = new Integer []{R.string.source_text1, R.string.source_text2, R.string.source_text3,
R.string.source_text6, R.string.source_text5, R.string.source_text4, R.string.source_text7,
R.string.source_text8, R.string.source_text9};
array_explain = new Integer []{R.string.source_text1_explain, R.string.source_text2_explain,
R.string.source_text3_explain,
R.string.source_text4_explain, R.string.source_text5_explain, R.string.source_text6_explain,
R.string.source_text7_explain,
R.string.source_text8_explain, R.string.source_text9_explain};
ArrayList<Integer> array_headingList = new ArrayList<Integer>(Arrays.asList(array_heading));
ArrayList<Integer> array_explainList = new ArrayList<Integer>(Arrays.asList(array_explain));
int_text = random.nextInt(array_headingList.size());
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
text_heading.setText(array_headingList.get(int_text));
text_explain.setText(array_explainList.get(int_text));
array_headingList.remove(int_text);
array_explainList.remove(int_text);
if(array_headingList.size() == 0){
click.setEnabled(false);
Toast.makeText(getApplicationContext(),"All text finished",Toast.LENGTH_SHORT).show();
} else if(array_headingList.size() == 1){
int_text = 0;
} else {
int_text = random.nextInt(array_headingList.size());
}
}
});

How to get the id of display image in flipper?

BELOW IS MY CODE. This code is working, but I want to get the value of the display image in array to test, if the display country is correct. Please help me . I'm stuck in this activity. Thanks for all help .
public class MainActivity extends Activity implements OnClickListener {
private boolean blocked = false;
private Handler handler = new Handler();
ViewFlipper flippy;
Button show;
TextView view;
int flags[] = { R.drawable.afghan, R.drawable.albania, R.drawable.algeria };
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.flipper);
flippy = (ViewFlipper) findViewById(R.id.viewFlipper1);
show = (Button) findViewById(R.id.button1);
view = (TextView) findViewById(R.id.textView1);
for (int i = 0; i < flags.length; i++) {
setflipperimage(flags[i]);
}
}
private void setflipperimage(int i) {
// TODO Auto-generated method stub
Log.i("Set Filpper Called", i + "");
ImageView image = new ImageView(getApplicationContext());
image.setBackgroundResource(i);
flippy.addView(image);
}
do not call this in loop,use this on click or on touch:
i+=1;
flippy.setDisplayedChild(flags[0]);
This will get used to get the current child id
viewFlipper.getDisplayedChild();

How do I delay text from being displayed in textView - using input from the user

I am trying to make a simple application where every so many seconds the text being displayed is changed to another, the input is given by the user before the onClick and set to different strings. I can't find a way to have the different strings displayed at different times - and is it even possible to use one single textView to display different text at different times, never at the same time....
Any help is appreciated. Thanks.
Andrew
This is my code so far...
public class ThunderActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//when the game button is pressed
final Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Enter names
//player one
final EditText player1 = (EditText) findViewById(R.id.editText1);
final String player = player1.getText().toString().trim();
//player 2
final EditText player2 = (EditText) findViewById(R.id.editText2);
final String player11 = player2.getText().toString().trim();
//player 3
final EditText player3 = (EditText) findViewById(R.id.editText3);
final String player111 = player3.getText().toString().trim();
//switches to second screen - the play xml file
setContentView(R.layout.main2);
//starts the song
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.drawable.thunderstruck);
mp.start();
//shuffle names and display them
//displays name - testing purposes
v = (TextView) findViewById(R.id.textView1);
String text = player;
((TextView) v).setText(text);
//v = (TextView) findViewById(R.id.textView2);
//String text2 = player11;
//((TextView) v).setText(text2);
}
});
}
}
An easier way to do the same thing is using the Handler.postDelayed method.
public class Act extends Activity{
private Handler handler = new Handler();
private TextView view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Initialize view
handler.postDelayed(new ViewUpdater("str1", view), 10000);
handler.postDelayed(new ViewUpdater("str2", view), 20000);
handler.postDelayed(new ViewUpdater("str2", view), 30000);
}
private class ViewUpdater implements Runnable{
private String mString;
private TextView mView;
public ViewUpdater(String string, TextView view){
mString = string;
mView = view;
}
#Override
public void run() {
mView.setText(mString);
}
}
}
Something like that: You get the basic idea!
ok here is your hint:
Say your TextView is called yourTextView
String[] texts = new String[]{"String1","String2","String3"}; //etc
Runnable myRun = new Runnable(){
public void run(){
for(int i=0;i<texts.length;i++){
synchronized(this){
wait(30000); //wait 30 seconds before changing text
}
//to change the textView you must run code on UI Thread so:
runOnUiThread(new Runnable(){
public void run(){
yourTextView.setText(texts[i]);
}
});
}
}
};
Thread T = new Thread(myRun);
T.start();
A more correct answer would be to use a ViewFlipper. You can add all your TextViews to it and call startFlipping(). You can set the flip interval by calling setFlipInterval(int milliseconds).

Categories

Resources