setCompoundDrawableWithIntrinsicBounds is not drawing anything...but only sometimes - android

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.

Related

Unity GameObject "flash" after SetActive on Android Project

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.

How to cancel all animations except of a specific one in Android studio

I have my code here and my problem is that I wish to have just one specific animation active when an if condition is satisfied.
You can see over my code that for doing this I need to separately close all the other animations in order to achieve my goal.
I want to know if is a clean way of doing this.
beaconManager = new BeaconManager(this);
beaconManager.setBackgroundScanPeriod(2000,20000);
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region region, List<Beacon> list) {
if (!list.isEmpty()) {
Beacon nearestBeacon = list.get(0);
int number = nearestBeacon.getMajor();
if(number == 1479)
{
Animation an = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.test);
blueButton.startAnimation(an);
yellowButton.clearAnimation();
blueButton2.clearAnimation();
orangeButton.clearAnimation();
orangeButton2.clearAnimation();
purpleButton.clearAnimation();
redButton.clearAnimation();
greenButton.clearAnimation();
}
if(number == 7574)
{
Animation an = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.test);
blueButton2.startAnimation(an);
blueButton.clearAnimation();
yellowButton.clearAnimation();
orangeButton.clearAnimation();
orangeButton2.clearAnimation();
purpleButton.clearAnimation();
redButton.clearAnimation();
greenButton.clearAnimation();
}
.
.
.
if(number == 61120)
{
Animation an = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.test);
yellowButton.startAnimation(an);
blueButton.clearAnimation();
blueButton2.clearAnimation();
orangeButton.clearAnimation();
orangeButton2.clearAnimation();
purpleButton.clearAnimation();
redButton.clearAnimation();
greenButton.clearAnimation();
}
}
}
});
region = new Region("ranged region", null, null, null);
}
You can also call anim.cancel(); but you should also call anim.reset(); immediately after it. Then when you want to start it again, just call startAnimation on the view.

If ImageView drawable equals a known drawable

I have an imageview that has its imageresource set programatically. This image could have had its resource set by any of 3 drawables, which is chosen using various variables earlier in the class.
The 3 drawables are:
R.drawable.well_done
R.drawable.try_again
R.drawable.sorry_failed
When I click on this image, it could have any of these three drawables set to it, so I'm trying to run a method something along the lines of this (I know this is totally wrong, but it might help visualise what I'm trying to do)
public void game(){
//STUFF
if(result>10){
imgView.setImageResource(R.drawable.well_done);}
//MORE STUFF
}
public void results_page(){
if(imgView=R.drawable.well_done){
//DO STUFF
}
if(imgView=R.drawable.try_again){
//DO STUFF
}
//etc...
}
Here is the proper code I have. Its a little more complex than my rubbish visualisation above, but I hope you understand what I'm trying to do.
ImageView iv_i;
//...
...onCreate(Bundle savedInstanceState){
//...
result1.setOnClickListener(onClL);
result2.setOnClickListener(onClL);
}
private void game() {
//...
result1.setImageResource(R.drawable.well_done);
result1.setTag(R.drawale.well_done)
result2.setImageResource(R.drawable.try_again);
result2.setTag(R.drawable.try_again);
//...
}
private OnClickListener onClL = new OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.result1:
ic_i = result1;
iv_i.setTag(result1.getTag());
break;
case R.id.result2:
iv_i = result2;
ic_i.setTag(result2.getTag());
break;
}
gotoResource();
}
};
private void gotoResource(){
Integer integer = (Integer) iv_i.getTag();
switch(integer){
case R.drawable.well_done:
//STUFF
break;
case R.drawable.try_again:
//STUFF
break;
case R.drawable.sorry:
//STUFF
break;
}
}
When I run this, I get a nullpointerexception at the line containing iv_i.setTag(result1.getTag());
What did i go wrong? Or how do I go about doing this properly, or another way of doing it that would be easier? Maybe converting the drawable to a string, then doing an if statement for the string, like: (also know this is completely wrong, but its just for a visualisation)
String resource = imgView.getDrawable().toString();
if(resource.equals("R.drawable.well_done")){
//DO SOMETHING
}
Thanks
Instead of relying upon the exact drawable the ImageView has, I suggest setting a tag on the ImageView to indicate which state it's in. I recently used this approach on a similar issue (determining whether a button is active or not), and it works well for me.
private static enum MessageViewType { SUCCESS, TRY_AGAIN, FAILURE }
public void game(){
//STUFF
if (result > 10){
imgView.setImageResource(R.drawable.well_done);}
imgView.setTag(R.id.image_view_status, MessageViewType.SUCCESS); // define image_view_status as a resource
}
//MORE STUFF
}
...
private void gotoResource(){
MessageViewType messageType = (MessageViewType) iv_i.getTag(R.id.image_view_status);
if (messageType == MessageViewType.SUCCESS) {
//STUFF
} else if (messageType == MessageViewType.TRY_AGAIN) {
// STUFF
} else if (messageType == MessageViewType.FAILURE) {
//STUFF
}
}
You can define the image_view_status id in any resource file. I personally use a file res > values > activity_resources.xml as follows:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="image_view_status" type="id" />
</resources>

Android Developement - If-Then-Else Statement. Switching images

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.

android unable to click button after return

I have a view to create an account. If the save button is clicked and any of the fields are left open, it displays a toast. If all fields are filled in, the account is saved. I tried to accomplish this with an onClickListener that has an iteration through all the fields. It works perfectly if a field is not filled in and it works perfectly if alle fields are filled, but when a field isn't filled, I type something in there, try to save again and the button doesn't do anything.
I think it has something to do with the return, but I don't know what to do else. If the return wouldn't be there, I would get a toast for each field that isn't filled in.
Here's the relevant code:
private void registerButtonListeners() {
mCRUDAccountButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mEditTexts.length; i++) {
if(mEditTexts[i].getText().length() == 0){
CommonCode.showToast(mNoTextTitles[i], mContext, mViewGroup);
mEmptyField = 1;
return;
}
};
if (mEmptyField == 0){
saveState();
}
}
});
}
thanks guys!
You're never resetting your flag back to 0!
so...
#Override
public void onClick(View v) {
mEmptyField = 0;//RIGHT HERE (give them the benefit of the doubt)
for (int i = 0; i < mEditTexts.length; i++) {
if(mEditTexts[i].getText().length() == 0){
CommonCode.showToast(mNoTextTitles[i], mContext, mViewGroup);
mEmptyField = 1; //You were too optimistic, they failed.
return;
}
};
if (mEmptyField == 0){
saveState();
}
}
});
Now, you're doing this test for the first time, every time. Otherwise, you go through and set that flag to 1, and next time, even though your loop never finds a match, when you get to the if mPentyField == 0 test, it fails cause you set that to 1 in the previous go around.

Categories

Resources