So What I would like to do here is that the starting image is assigned with Tag 0. When I run the method, I want the image to change to gallows1 and get a tag of "1". Then when its run again, I want it to keep gallows1 with a tag of 1, and then change it to gallows2, and reassign it.... Basically, I want 1 image to change to the next, and so forth as the method runs 6 times.
Here is what I have so far.
public void switchImage(View view) {
ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setTag("0");
if (img.getTag() == "0") {
img.setImageResource(R.drawable.gallows1);
img.setTag("1");
} else if (img.getTag() == "1") {
img.setImageResource(R.drawable.gallows2);
img.setTag("2");
} else if (img.getTag() == "2") {
img.setImageResource(R.drawable.gallows3);
img.setTag("3");
} else if (img.getTag() == "3") {
img.setImageResource(R.drawable.gallows4);
img.setTag("4");
} else if (img.getTag() == "4") {
img.setImageResource(R.drawable.gallows5);
img.setTag("5");;
} else if (img.getTag() == "5") {
img.setImageResource(R.drawable.gallows6);
img.setTag("6");
} else if (img.getTag() == "6") {
return;
}
}
The Game I am making is hangman, but instead of using graphics, I wanted to have a twist (its for a challenge proj) and have progressing images show up instead.
Put this outside the method:
ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setTag("0")
and remove img.setTag("0") from inside the method
The way you have it now, img.setTag("0") gets called everytime so it will always just hit the first if block. If you move it outside, then the first time the method is called, if block 1 will match, then the next time, if block 2, etc.
Related
I have a project that use Android to display Unity Player. So I export Untiy project as Android module which implemented by Android Application.
I create buttons in Android Activity which contains UnityPlayer, And when I click button, it send a message to Unity Player to invoke C# function, just like this:
findViewById(R.id.btnChange).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mUnityPlayer.UnitySendMessage("ScriptHolder", "ChangeSkin", "");
}
});
And the function named "ChangeSkin" is just to change some GameObjects' active. Just like this:
void ChangeSkin()
{
int prefab;
if (_currentPrefab == PREFAB_DEFAULT)
{
prefab = PREFAB_PRINCESS;
}
else
{
prefab = PREFAB_DEFAULT;
}
ShowSkin(prefab);
}
private void ShowSkin(int prefab)
{
_currentPrefab = prefab;
foreach (var item in _defaultDressList)
{
item.SetActive(prefab == PREFAB_DEFAULT);
}
foreach (var item in _princessDressList)
{
item.SetActive(prefab == PREFAB_PRINCESS);
}
}
And something weird happening: when I click button to change the person's cloth in Unity, the GameObjects which called SetActive(true) show at the position above the right position for a frame and become normal, it looks like they flash. Here is the gif of the project demo:
It looks like the position offset is equal to the height of status bar. If I create a button on Unity Scene and call "ChangeSkin" function, everything will be OK.
I tried all I can to fix this but not succeed. So I hope you will help me, thx.
You should check your Unity layout. If you have a layout group that has content size fitter component, and the child objects also have it (content size fitter), this could cause these glitches.
I fixed this problem by using a flag (or trigger). Just like this:
// set value true to trigger ChangeSkin() in Update(),
// instead of invoke ChangeSkin() directly
private bool _changingSkinTrigger = false;
void ChangeSkin()
{
if (_currentPrefab == PREFAB_DEFAULT)
{
_currentPrefab = PREFAB_PRINCESS;
}
else
{
_currentPrefab = PREFAB_DEFAULT;
}
_changingSkinTrigger = true;
}
void Update()
{
if (_changingSkinTrigger)
{
_changingSkinTrigger = false;
ShowSkin();
}
}
private void ShowSkin()
{
foreach (var item in _defaultDressList)
{
item.SetActive(_currentPrefab == PREFAB_DEFAULT);
}
foreach (var item in _princessDressList)
{
item.SetActive(_currentPrefab == PREFAB_PRINCESS);
}
}
Thank #AndriyMarshalek for enlightening me.
I have RecyclerView which contains user bookmarks. The plan is bookmarked item will be marked with certain icon. This is my code in onBindViewHolder():
// ...
if (bookmarks != null) {
for (BookmarkModel bookmarkData : bookmarks) {
if (bookmarkData.getLetterId() == letter && bookmarkData.getEntryId() == entry) {
holder.imgBookmark.setVisibility(View.VISIBLE);
} else {
holder.imgBookmark.setVisibility(View.INVISIBLE);
}
}
}
However, the RecyclerView is not showing all bookmark icons, only a few of them. Currently I have 3 bookmarks yet it only shows 1 of them. I have debug it and verified that holder.imgBookmark.setVisibility(View.VISIBLE) have been called 3 times. How to update the image properly?
I forgot to put break when the letter and entry match. Because of it, only the last match would show the icon.
if (bookmarks != null) {
for (BookmarkModel bookmarkData : bookmarks) {
if (bookmarkData.getLetterId() == letter && bookmarkData.getEntryId() == entry) {
holder.imgBookmark.setVisibility(View.VISIBLE);
break;
} else {
holder.imgBookmark.setVisibility(View.INVISIBLE);
}
}
}
I am creating some buttons programatically, I am adding the buttons this way:
final Button btn = new Button(this);
btn.setText(array.get(i));
btn.setTextSize(10);
btn.setTextColor(getColor(R.color.white));
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
goToModule(texto);
}
});
btn.setHeight(height);
btn.setWidth(width);
btn.setOnTouchListener(parentListener);
btn.post(new Runnable() {
#Override
public void run() {
btn.setCompoundDrawablesWithIntrinsicBounds(null,getDrawableForText(texto),null, null);
btn.setPadding(0,35,0,0);
btn.setBackground(gd);
btn.setLayoutParams(params);
}
});
row1.addView(btn);
Up to 19 buttons can be drawn. They are inside a ViewFlippers, so the user can page between pages
The getDrawableForText method:
private Drawable getDrawableForText(String texto) {
Drawable drawable=null;
if(texto.equalsIgnoreCase("Viajes")){
Log.i("LOG", "This drawable is the problematic one");
}
if (texto.equals(textosBotones[0])) {
drawable=getResources().getDrawable(R.drawable.vuelo,getTheme());//Viajes
} else if (texto.equals(textosBotones[1])) {
drawable=getResources().getDrawable(R.drawable.hotel,getTheme());//Hotel
} else if (texto.equals(textosBotones[2])) {
drawable=getResources().getDrawable(R.drawable.agenda,getTheme());//Agenda
/*int h = btn.getHeight()-100;
int w = btn.getWidth()-100;
drawable.setBounds( 0, 0, w, h );
Bitmap icon= BitmapFactory.decodeResource(getResources(),R.drawable.agenda);
Bitmap newbitMap = Bitmap.createScaledBitmap(icon,w,h, true);
dr = new BitmapDrawable(EventActivity.this.getResources(), newbitMap);*/
} else if (texto.equals(textosBotones[3])) {
drawable=getResources().getDrawable(R.drawable.ponentes,getTheme());//Ponentes
} else if (texto.equals(textosBotones[4])) {
drawable=getResources().getDrawable(R.drawable.documentos,getTheme());//Documentos
} else if (texto.equals(textosBotones[5])) {
drawable=getResources().getDrawable(R.drawable.ubicacion,getTheme());//Ubicaciones
} else if (texto.equals(textosBotones[6])) {
drawable=getResources().getDrawable(R.drawable.contactos,getTheme());//Contactos
} else if (texto.equals(textosBotones[7])) {
//drawable=getResources().getDrawable(R.drawable.preguntas,getTheme());//Encuestas
drawable=getResources().getDrawable(R.drawable.valoracion,getTheme());//Encuestas/valoraciones
} else if (texto.equals(textosBotones[8])) {
drawable=getResources().getDrawable(R.drawable.qr,getTheme());//Distintivo/best business
} else if (texto.equals(textosBotones[9])) {
drawable=getResources().getDrawable(R.drawable.info,getTheme());//Forum
} else if (texto.equals(textosBotones[10])) {
drawable=getResources().getDrawable(R.drawable.galeria,getTheme());//GalerĂa
} else if (texto.equals(textosBotones[11])) {
drawable=getResources().getDrawable(R.drawable.chat,getTheme());//Chats
} else if (texto.equals(textosBotones[12])) {
drawable=getResources().getDrawable(R.drawable.muro,getTheme());//Muro
} else if (texto.equals(textosBotones[13])) {
drawable=getResources().getDrawable(R.drawable.asistentes,getTheme());//Asistentes
} else if (texto.equals(textosBotones[14])) {
drawable=getResources().getDrawable(R.drawable.twitter,getTheme());//Twitter
} else if (texto.equals(textosBotones[15])) {
drawable=getResources().getDrawable(R.drawable.twitter,getTheme());//Facebook
} else if (texto.equals(textosBotones[16])) {
drawable=getResources().getDrawable(R.drawable.twitter,getTheme());//Instagram
} else if (texto.equals(textosBotones[17])) {
drawable=getResources().getDrawable(R.drawable.qr,getTheme());//QR
} else if (texto.equals(textosBotones[18])) {
drawable=getResources().getDrawable(R.drawable.valoracion,getTheme());//Proveedores
} else if (texto.equals(textosBotones[19])){
/*drawable = DrawableCompat.wrap(getResources().getDrawable(R.drawable.trophy,getTheme()));
DrawableCompat.setTint(drawable, getColor(R.color.white));*/
/*drawable=getResources().getDrawable(R.drawable.trophy,getTheme());
Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(wrappedDrawable, getColor(R.color.white));
drawable=wrappedDrawable;*/
drawable=getResources().getDrawable(R.drawable.actividad, getTheme());//Actividades
}else if(texto.equals(textosBotones[20])){
drawable=getResources().getDrawable(R.drawable.noticias,getTheme());
}else{
Log.i("LOG", "Something weird happened");
}
return drawable;
}
The first time I enter this Activity, the drawable is drawn correctly. BUT, if I click one of the buttons (which goes to another Activity), and inside that new Activity, I click on a Button that goes to a third Activity, if I go back to the main Activity(where the buttons are) there is one drawable that is not drawn, its always the same, the first one. Th rest of the drawable of the rest of the buttons are drawn ok.
The main Activity is not recreated again, it remains in memory. Anyway, if I draw it again, the same weird behaviour happens.
I am pretty lost, since the third Activity is not affectin the first one in any way.
Someone could guide me about what is happening?
Thank you.
PD: If you need further details, please let me know.
EDIT:
In third Activity, I am doing something like this:
private void getArrivalsFromJSON(String resp) {
arrivals=new ArrayList<>();
ArrivalModel all=new ArrivalModel();
all.setDestination("");
all.setTerminal("ALTTODO");
all.setType("");
arrivals.add(all);
try {
JSONObject json=new JSONObject(resp);
JSONArray data=json.getJSONArray("data");
for(int i=0;i<data.length();i++){
JSONObject obj=data.getJSONObject(i);
ArrivalModel arrival=new ArrivalModel();
arrival.setDestination(obj.getString("destination"));
arrival.setTerminal(obj.getString("terminal"));
arrival.setType(obj.getString("type"));
arrivals.add(arrival);
}
generateLayout();
} catch (JSONException e) {
e.printStackTrace();
}
}
In thath for, if I modify the line:
for(int i=0;i<data.length();i++)
and change it like this:
for(int i=0;i<data.length()-7;i++)
The button drawable it is drawn normally! I have checked in the Android Studio profiler, and it is never using more than 90Mb of RAM. It is too much?
I found the error. Was not related with memory, or other performance issues.
What was happening is, in the third Activity I was using the same .png I was using in the button, but I was changing its color:
d.setColorFilter(new PorterDuffColorFilter(Color.parseColor(color), PorterDuff.Mode.MULTIPLY));
So, when I was going back to the first Activity, and tried to draw the Drawable, it was drawing, but with its color changed. Given that the button color, and the color I was changing the drawable with was the same, it appeared that the drawable was not being drawn; it fact it was being drawn, but was not visible.
This is for the game i am doing
When I click the Home button on the android I want it to save the frame it was in and not start the game loads where it was
This results in saving the game forever but I just want it to save once and the code to load does not work
import flash.net.SharedObject;
stage.addEventListener(KeyboardEvent.KEY_DOWN, buttonPressed);
var stateSO:SharedObject = SharedObject.getLocal("saveState");
if (stateSO.size > 0 && stateSO.data.lastFrame && stateSO.data.lastFrame != undefined) {
//the shared object exists and has a valid value, so lets skip to that frame
gotoAndPlay(stateSO.data.lastFrame);
trace("Load Here.");
}
function buttonPressed(event:KeyboardEvent):void{
if (event.keyCode == Keyboard.MENU){
//this function runs every frame
function saveState(Event){
stateSO.flush(); //save the cookie (shared object)
trace("Save Here.");
return;
}
addEventListener(Event.ENTER_FRAME, saveState);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, buttonPressed);
}
}
thanks for help
There's unnecessary code inside your keypress event handler (and other places), and you never actually write the value you want to save. Also, always format your code because a lot of errors could occur just because you cannot read clearly what your code is actually doing.
import flash.net.SharedObject;
var stateSO:SharedObject;
// I guess this is a frame script, lets run it
// only once to avoid the possible mess.
if (!stateSO)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, buttonPressed);
stateSO = SharedObject.getLocal("saveState");
if (stateSO.data.lastFrame != undefined)
{
trace("Load Here.");
gotoAndPlay(stateSO.data.lastFrame);
}
}
function buttonPressed(e:KeyboardEvent):void
{
// I hope you know what this button is.
if (e.keyCode == Keyboard.MENU)
{
saveState();
}
}
function saveState():void
{
// Write current frame to the SharedObject.
stateSO.data.lastFrame = currentFrame;
stateSO.flush();
trace("Save Here.");
}
This is quite a tricky one. I thought I had it resolved as it was working with my S2. But the problem has come back during testing HTC One M7.
I have a welcome screen kind of app, which keeps displaying random (or same selected) images from a storage folder whenever user switches phone on.
I'm preparing image view in OnResume, where I'm calling my image drawing method.
protected void onResume() {
super.onResume();
if (isCallActive(this) == false) {
changeImage(false);
} else {
}
}
ChangeImage method code is:
public void changeImage(Boolean vForce) {
String pathV = null;
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Boolean vPicChosen;
vPicChosen = pref.getBoolean("PicChosen", false);
if (vPicChosen == true) {
pathV = pref.getString("PicURL", "NOPIC");
} else pathV = "NOPIC";
if (pathV == "NOPIC" || vForce == true) {
pathV = randomPic();
}
imgFile = new File(pathV);
if(imgFile.exists()) {
img1 = (ImageView)findViewById(R.id.imageView);
Display display = getWindowManager().getDefaultDisplay();
float width = display.getWidth();
float height = display.getHeight();
if (reusedBitmap != null && !reusedBitmap.isRecycled()) {
//reusedBitmap.recycle();
}
reusedBitmap = decodeSampledBitmapFromPath(pathV, (int)width, (int)height);
img1.setImageBitmap(reusedBitmap);
}
else
Toast.makeText(this, "no Image present", Toast.LENGTH_SHORT).show();
}
Now with this code, every time my app was presenting an image (same or different), the memory heap was growing by 3 to 6MB, depending upon the image size. After 5-6 screen switchons, the memory would go beyond 50Mb, and eventually result in out of memory, or app being killed.
So I tried many things, and eventually succeeded in keeping a tab on memory by recycling the bitmap in onStop method:
#Override
protected void onStop() {
Log.i("event","onStop");
if (reusedBitmap != null && !reusedBitmap.isRecycled()) {
reusedBitmap.recycle();
}
}
As I mentioned earlier, this used to work fine on my S2.
But on my HTC One M7, due to this call, image drawing is throwing error
12-03 16:21:12.944: E/AndroidRuntime(25881): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#41af3468
If I remove this line from onStop, the memory growing problem comes back.
Any suggestion please?