有时ImageView中的图像不显示

时间:2015-08-19 08:55:40

标签: android imageview

在活动中有4个视图,用户可以在其中下注"关于问题的正确答案,根据当前答案中的当前金额,金额的图像会发生变化(从零开始到一包金钱,最多只需一堆钱)。

有时当将值添加到视图时(通过触摸/点击或通过从另一个答案拖动它),图像不会显示(只有在此答案之前没有任何金钱时才会出现)。

这是View代码(我添加了几个日志和注释):

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class SuperMoneyView extends LinearLayout
{
    protected TextView _moneyValueTextView;
    protected ImageView _moneyPacktView;
    protected long _value = 1000000;
    private Activity _activity;
    protected boolean _isSoundActive = false;

    public SuperMoneyView(Context context)
    {
        this(context, null);
    }

    public SuperMoneyView(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public SuperMoneyView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        initConfig(true);
    }

    public SuperMoneyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
    {
        super(context, attrs, defStyleAttr, defStyleRes);
        initConfig(true);
    }

    public void initConfig(boolean setDefaultValues)
    {
        setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
    }

    public void setActivity(Activity activity)
    {
        _activity = activity;
    }

    public View getMoneyValueView()
    {
        return _moneyValueTextView;
    }

    public void setImage(final Drawable drawable)
    {
        Log.e("AnswerView", "setImage");
        if(drawable == null)
        {
            Log.e("AnswerView", "setImage -- Drawable Null");
            _moneyPacktView.setVisibility(View.INVISIBLE);
            return;
        }
        else
        {
            Log.e("AnswerView", "setImage -- Drawable Not Null");
            _moneyPacktView.setVisibility(View.VISIBLE);
        }

        if(_moneyPacktView != null)
        {//This part is executed but the image does not show
            Log.e("AnswerView", "setImage -- Real set image");
            _moneyPacktView.setImageDrawable(drawable);
            _moneyPacktView.setAlpha(1.0f);
            _moneyPacktView.setVisibility(View.VISIBLE);
            invalidate();
        }
    }

    public ImageView getMoneyImageView()
    {
        return _moneyPacktView;
    }

    public boolean isSoundActive()
    {
        return _isSoundActive;
    }
    public void setSoundActive(boolean active)
    {
        _isSoundActive = active;
    }

    public long getValue()
    {
        return _value;
    }
    public void setValue(long value)
    {
        setValue(value, _value);
    }
    public void setValue(long value, long oldValue)
    {
        final boolean playSound = value > oldValue;
        _value = value;

        if(_activity == null)
        {//This part is never executed (Activity is always different than null)
            Log.e("AnswerView", "SetValue no Activity");
            realSetValue(playSound);
        }
        else
        {
            try
            {
                _activity.runOnUiThread(//I tried this, because I thought that maybe it wasn't running on the UI Thread
                        new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                realSetValue(playSound);
                            }
                        }
                );
                Log.e("AnswerView", "SetValue Activity");
            }
            catch(Exception e)
            {//Never called either
                e.printStackTrace();
                Log.e("AnswerView", "SetValue Catch");
                realSetValue(playSound);
            }
        }
    }
    private void realSetValue(boolean sound)
    {
        Log.e("AnswerView", "RealSetValue");
        if(_moneyValueTextView != null)
        {
            Log.e("AnswerView", "_moneyValueTextView != null");
            if(sound && isSoundActive())
            {
                Log.e("AnswerView", "Sound Active");
                MediaUtils.playMoneyDrag();
            }
            _moneyValueTextView.setText("" + _value);
        }
        if(_moneyPacktView != null)
        {//Always different than null
            Log.e("AnswerView", "_moneyPacktView != null");
            setImage(getImageForAmount(_value));
        }
    }

    public void updateValue(long toAdd)
    {
        long oldValue = _value;

        _value += toAdd;
        if(_value < 0l)
        {
            _value = 0l;
        }
        setValue(_value, oldValue);
    }

    public void setWrong()
    {
        if(getValue() > 0)
        {
            RemoveMoneyAnimation animation = new RemoveMoneyAnimation(_moneyPacktView);
            animation.setDuration(1000);
            startAnimation(animation);
        }
    }

    private Drawable getImageForAmount(long amount)
    {
        if(amount == 0)
        {
            Log.e("AnswerView", "getImageForAmount -- amount == 0 -- Null");
            return null;
        }
        else if(amount <= 50000)
        {
            Log.e("AnswerView", "getImageForAmount -- icn_money_pack_bet_single");
            return getContext().getResources().getDrawable(R.drawable.icn_money_pack_bet_single);
        }
        else if(amount <= 150000)
        {
            Log.e("AnswerView", "getImageForAmount -- icn_money_pack_bet_medium");
            return getContext().getResources().getDrawable(R.drawable.icn_money_pack_bet_medium);
        }
        else if(amount <= 500000)
        {
            Log.e("AnswerView", "getImageForAmount -- icn_money_pack_bet_full");
            return getContext().getResources().getDrawable(R.drawable.icn_money_pack_bet_full);
        }
        else if(amount <= 1000000)
        {
            Log.e("AnswerView", "getImageForAmount -- icn_money_pack_bet_extra_full");
            return getContext().getResources().getDrawable(R.drawable.icn_money_pack_bet_extra_full);
        }
        Log.e("AnswerView", "getImageForAmount -- Null");
        return null;
    }

    protected class RemoveMoneyAnimation extends Animation implements Animation.AnimationListener
    {
        final View _view;
        final float _initialWidth;
        final float _initialHeight;

        public RemoveMoneyAnimation(View view)
        {
            _view = view;
            _initialWidth = _view.getWidth();
            _initialHeight = _view.getHeight();

            setAnimationListener(this);
        }

        public void restoreViewSize()
        {
            _view.getLayoutParams().width = (int)_initialWidth;
            _view.getLayoutParams().height = (int)_initialHeight;
            _view.setLayoutParams(_view.getLayoutParams());
            _view.setRotation(0.0f);
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t)
        {
            try
            {
                if(interpolatedTime > 0.5f)
                {
                    _view.setAlpha(1.0f + (-1.0f * (interpolatedTime - 0.5f) * 2.0f));
                }
                _view.getLayoutParams().width = (int)(_initialWidth - (_initialWidth * interpolatedTime));
                _view.getLayoutParams().height = (int)(_initialHeight - (_initialHeight * interpolatedTime));
                _view.setLayoutParams(_view.getLayoutParams());
                _view.setRotation(0.0f + (360.0f * interpolatedTime * 2.0f));


            }catch(Exception e){e.printStackTrace();}
        }

        @Override public boolean willChangeBounds() { return true; }

        @Override
        public void onAnimationStart(Animation animation)
        {
            Handler handler = new Handler();
            handler.postDelayed(
                    new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            try
                            {
                                _activity.runOnUiThread(
                                        new Runnable()
                                        {
                                            @Override
                                            public void run()
                                            {
                                                restoreViewSize();
                                            }
                                        }
                                );
                            }catch(Exception e){ e.printStackTrace(); }
                        }
                    },
                    getDuration()
            );
        }

        @Override
        public void onAnimationEnd(Animation animation){

        }

        @Override
        public void onAnimationRepeat(Animation animation){

        }
    }
}

基本上每次调用setValue(强制值)或updateValue(加上或减去当前值)时,都会调用方法setImage来设置相应的图像。 根据日志我得出以下结论:

  • ImageView大小总是不同于0(在Nexus 5上固定在312x256左右)
  • 始终选择正确的图像
  • 代码在UI线程
  • 上运行
  • 使用正确的drawable
  • 调用setImageDrawable

我对可能出现问题的想法用尽了,任何人都有线索?

编辑:添加了扩展类和XML代码的代码

这是AnswerView类,它扩展了SuperMoneyView以添加TextView方法

public class AnswerView extends MoneyView
{
    TextView _answerTextView;
    LinearLayout _answerBoxLinerLayout;
    RelativeLayout _betBoxContainerRelativeLayout;

    private String _answer = "";

    public AnswerView(Context context)
    {
        this(context, null);
    }

    public AnswerView(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public AnswerView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        initConfig(true);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public AnswerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
    {
        super(context, attrs, defStyleAttr, defStyleRes);
        initConfig(true);
    }

    @Override
    public void initConfig(boolean setDefaultValues)
    {
        super.initConfig(setDefaultValues);

        _answerTextView = (TextView)findViewById(R.id.answerTextView);
        _moneyValueTextView = (TextView)findViewById(R.id.moneyBetTextView);
        _moneyPacktView = (ImageView)findViewById(R.id.betBoxTextView);
        _answerBoxLinerLayout = (LinearLayout)findViewById(R.id.answerBoxLinerLayout);
        _betBoxContainerRelativeLayout = (RelativeLayout)findViewById(R.id.betBoxContainerRelativeLayout);

        setAnswer(_answer);
        setValue(0l);
    }

    public TextView getTextView()
    {
        return _answerTextView;
    }

    public String getAnswer()
    {
        return _answer;
    }
    public void setAnswer(String answer)
    {
        if(answer == null){ answer = ""; }

        _answer = answer;
        if(_answerTextView != null)
        {
            _answerTextView.setText(_answer);
        }
    }

    public void setNormal()
    {
        _answerBoxLinerLayout.setBackgroundResource(R.drawable.bg_dark_gray_square_blue_border);
        setValue(0l);
        setAlpha(1.0f);
    }
}

在用户选择start(布局已经绘制并且可见)之后,活动会调用类initConfig

这是XML代码

<?xml version="1.0" encoding="utf-8"?>
<com.test.game.views.game.AnswerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@android:color/transparent">

    <com.walkme.moneyquiz.views.extended.AutoResizeTextView
        android:id="@+id/answerTextView"
        style="@style/answerTextViewStyle"
        android:text="All at the same time"/>

    <LinearLayout
        android:id="@+id/answerBoxLinerLayout"
        style="@style/answerBetBoxStyle"
        android:orientation="vertical"
        android:background="@drawable/bg_dark_gray_square_blue_border">

        <RelativeLayout
            android:id="@+id/betBoxContainerRelativeLayout"
            style="@style/moneyPackBetRelativeLayoutStyle">

            <ImageView
                android:id="@+id/betBoxTextView"
                style="@style/moneyPackBetImageInRelativeLayoutStyle"
                android:src="@drawable/icn_money_pack_bet_extra_full"/>

        </RelativeLayout>

        <com.walkme.moneyquiz.views.extended.AutoResizeTextView
            android:id="@+id/moneyBetTextView"
            style="@style/betValueTextStyle"
            android:text="5.000$"
            android:singleLine="true"/>

    </LinearLayout>

</com.test.game.views.game.AnswerView>

使用includeTableRow标记添加到主布局中,weight分布相等<style name="answerTextViewStyle"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">0dp</item> <item name="android:layout_weight">1</item> <item name="android:layout_margin">@dimen/marginSmall</item> <item name="android:padding">@dimen/marginSmall</item> <item name="android:textColor">@color/white</item> <item name="android:textSize">@dimen/textSizeSmall</item> <item name="android:gravity">center</item> <item name="android:background">@color/mainBlue</item> </style> <style name="answerBetBoxStyle"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">0dp</item> <item name="android:layout_weight">1</item> <item name="android:layout_margin">@dimen/marginSmall</item> <item name="android:background">@android:color/transparent</item> </style> <style name="moneyPackBetRelativeLayoutStyle"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:background">@android:color/transparent</item> <item name="android:layout_gravity">center</item> </style> <style name="moneyPackBetImageInRelativeLayoutStyle"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:maxHeight">@dimen/imageHeightMedium</item> <item name="android:adjustViewBounds">true</item> <item name="android:background">@android:color/transparent</item> <item name="android:scaleType">centerInside</item> <item name="android:layout_gravity">center</item> <item name="android:layout_centerInParent">true</item> </style> <style name="betValueTextStyle" > <item name="android:layout_width">match_parent</item> <item name="android:layout_height">0dp</item> <item name="android:layout_weight">0.5</item> <item name="android:textColor">@color/white</item> <item name="android:textSize">@dimen/textSizeMedium</item> <item name="android:gravity">center</item> </style>

以下是使用的样式:

$(window).resize(function() {
   if($('.uk-hidden-small').is(':hidden')) {
   //code to run when it's hidden
   } else {
   //code to run when it's shown (if necessary)
   }
});

2 个答案:

答案 0 :(得分:1)

调用无效后检查图像大小。如果大小错误,则强制它是正确的。

答案 1 :(得分:0)

根据我从您的代码中了解到的内容,_moneyPacktView的默认图片未设置。当getImageForAmount()为0,null返回给定,setImage()为null参数时,仅将_moneyPacktView设置为可见。也许这就是你的图像没有显示的原因。也许您可以在setImage()

中添加以下null参数代码
if(drawable == null)
{
  Log.e("AnswerView", "setImage -- Drawable Null");
  _moneyPacktView.setImageDrawable(getContext().getResources().getDrawable(R.drawable.anyDefaultImage));
  _moneyPacktView.setAlpha(1.0f);
  _moneyPacktView.setVisibility(View.VISIBLE);
  invalidate();
}

或在getImageForAmount()

 if(amount == 0)
 {
   Log.e("AnswerView", "getImageForAmount -- amount == 0 -- Null");
   return getContext().getResources().getDrawable(R.drawable.anyDefaultImage);
 }