Android 4.4.2 creates a black mask outside view ob

2020-04-21 01:29发布

问题:

Really need some help on this...

Please take a look to this simple FadeIn animation of an ImageView, using full java code. Recreate it using API's 21, 18, 17, 16.. works perfect. Now try it with API 19 (android 4.4.2), funny mask created (see explanation bellow):

public class _ExampleAnimationNotWorking extends Activity {
Common common; // my own class to read assets
FrameLayout fl;
ImageView iv;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.common = new Common(this,this);
    this.fl = new FrameLayout(this);
    this.iv = new ImageView(this);

    FrameLayout.LayoutParams flparam = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT);
    LayoutParams lparam = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

    iv.setImageBitmap(common.newImage("iv_image.png", ImageFormat.RGB565).getBitmap());
    iv.setX(50);
    iv.setY(0);

    fl.addView(iv, lparam);
    this.setContentView(fl, flparam);

    AlphaAnimation animation = new AlphaAnimation(0,1);
    animation.setDuration(3000);
    iv.setAnimation(animation); // may skip frames if not used in API19 (thats another problem)
    iv.startAnimation(animation);
} ....

During animation, Android 4.4.2 (API19) is creating a black mask outside the ImageView size boundary, starting at x/y coordinates (0 + imageWidth / 0 + imageHeight), so if you initially place the image outside that coordinate, you don’t see any animation, just the original image at the end of the animation.To recreate the issue, I have placed the image in x = 50 . You would see that the half right side of the image is black during Android 4.4.2 animation. You can recreate using emulator with any size of screen setup that you prefer.

Changing "lparam" from WRAP_CONTENT to MATCH_PARENT or other width/height is not the solution. It should the same way that in other versions (Note i try it also in 4.4.3 and 4.4.4 and works perfect). This maybe a bug on 4.4.2 java code animation, because if you use XML method, it work perfect on API19. I need a solution or work around on this, because my entire project is based on pure java code, and can't exclude KitKat 4.4.2 as a target on the project.

Thanks.

PD:> Some people are here for what?. It was ok to correct my post, but taking me -2 points for that? is not a solution to my issue, and more if I need some points to attach the images related to this problem. Thank you CBredlow !

EDITED: I need to upload the pictures that explain this issue, but since SO its not so friendly to new users, just follow this link to see the images:

http://forum.xda-developers.com/showpost.php?p=56553476&postcount=2

回答1:

! SOLVED !

For some reason, API19 programmatically pure java animations doesn't play very well with absolute settings, like setX() or setY(). Experts may take a look on this. API19 prefers to work with margins on the layout parameter side.

The following procedure, apply's to android 4.4.2. Of course, it works on the others versions down and up, but you must change your way of thinking. You must place an imagen programmatically using layout parameters, so change:

iv.setX(50);
iv.setY(0);

to

lparam.setMargins(50, 0, 0, 0);
iv.setLayoutParams(lparam);
iv.requestLayout();

you can also use (for API >=17)

lparam.setMarginStart(50); // for x pos
lparam.setMarginEnd(0);  // for y pos

You must call "requestLayout()" to ensure that the new changes on the layout, will be committed when adding the view to the parent (fl).

Finally, by mistake, I use "LayoutParams" instead of "FrameLayout.LayoutParams". This has nothing to do with the issue and was not affecting it, but this is the correct way to define it, so change:

LayoutParams lparam = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

to

FrameLayout.LayoutParams lparam = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);

The complete working code for any API is:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Common common = new Common(this, this);
    FrameLayout fl = new FrameLayout(this);
    ImageView iv = new ImageView(this);

    FrameLayout.LayoutParams flparam = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
    FrameLayout.LayoutParams lparam = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);

    iv.setImageBitmap(common.newImage("100x100.png", ImageFormat.RGB565).getBitmap());
    lparam.setMarginStart(50);
    lparam.setMarginEnd(0);
    iv.setLayoutParams(lparam);
    iv.requestLayout();

    fl.addView(iv);
    this.setContentView(fl, flparam);

    AlphaAnimation animation = new AlphaAnimation(0, 1);
    animation.setDuration(3000);
    iv.setAnimation(animation);
    iv.startAnimation(animation);
}