安卓图片视图渐变背景

4
所以,我想更新一个ImageView,根据手机陀螺仪和光传感器的一些事件来改变渐变。然而,此时我正在尝试使用单击事件进行测试。
我想设置一个径向渐变,其中心在单击事件处。我首先尝试根据这个想法设置布局背景,一切都很顺利。然后我尝试将其更改为布局中所需的可视元素大小和位置的ImageView,但渐变中心会向下和向右移动。
以下是代码:
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_seeker);

    RelativeLayout layout = (RelativeLayout) findViewById(R.id.seeker_layout);

    layout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {

                int location[] = new int[2];
                //measuring location of Image View to try and find correlation to shift
                findViewById(R.id.gradient_indicator).getLocationOnScreen(location);
                int grad_height = findViewById(R.id.gradient_indicator).getMeasuredHeight();
                int grad_width = findViewById(R.id.gradient_indicator).getMeasuredWidth();
                final float pos_x = event.getX();
                final float pos_y = event.getY();
                Toast position = Toast.makeText(getApplicationContext(), "Event Position (" + String.valueOf(pos_x) + "x" + String.valueOf(pos_y) + ")\n Window Dimensions(" + grad_width + "x" + grad_height + ")\n Window Position(" + location[0] + "x" + location[1] + ")", Toast.LENGTH_LONG);
                position.show();

                ShapeDrawable.ShaderFactory shader_factory = new ShapeDrawable.ShaderFactory() {

                    @Override
                    public Shader resize(int width, int height) {
                        RadialGradient radialGradient = new RadialGradient(pos_x, pos_y, 350, 0xff0000ff, 0, Shader.TileMode.MIRROR);
                        return radialGradient;
                    }
                };

                //Set curve radius to equal values in dp as specified in loaded xml shape
                float dp_radius = 5;
                int curve = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp_radius, getResources().getDisplayMetrics());
                float[] r_radii = new float[8];
                Arrays.fill(r_radii,curve);

                //create shape programatically that matches xml one
                RoundRectShape rs = new RoundRectShape(r_radii, null, null);
                ShapeDrawable sd = new ShapeDrawable(rs);
                sd.setShaderFactory(shader_factory);

                ImageView gradient_indicator = (ImageView) findViewById(R.id.gradient_indicator);

                if (Build.VERSION.SDK_INT >= 15) {
                    setBackgroundV15Plus(gradient_indicator, sd);
                } else {
                    setBackgroundV15Minus(gradient_indicator, sd);
                }


            }
            return true;
        }
    });
}
@TargetApi(15)
private void setBackgroundV15Plus(View view, ShapeDrawable sd) {
    view.setBackground(sd);

}

@SuppressWarnings("deprecation")
private void setBackgroundV15Minus(View view, ShapeDrawable sd) {
    view.setBackgroundDrawable(sd);
}

这里有一张图片展示了我得到的结果,我用红圈标出了光标的位置。错位的渐变


1
如果在布局背景中使用时它是正常工作的,我敢打赌如果你将ImageView设置为全屏,它应该可以工作,也许你需要从ImageView位置偏移x和y。你有没有注意到当在布局背景中使用时,中心会稍微向下偏移? - Nanoc
问题的根源似乎是在xml中设置了边距或填充。如果我在ImageView本身上设置边距或在容纳图像的相对视图上设置填充,它将持续存在。如果我将其带到全屏状态下就没有问题了。我可以通过从实际的点击事件中减去边距像素来解决它。然而,我希望能够更优雅地解决这个问题,也许当调用Shader resize函数时可以解决。 - Mauricio Aguilar Cardenas
如果您不想让ImageView全屏显示,那么这是唯一的方法,在IOS中,您有一个内置函数,可以将触摸事件偏移给定视图,在Android中,您必须手动完成。无论如何,您所有的问题都是由于没有阅读此内容引起的 :) http://stackoverflow.com/questions/29956014/why-should-we-use-xml-layouts - Nanoc
那篇文章并没有真正评论需要从事件程序化更新xml形状的渐变/背景所带来的负面影响。事实上,我想保持纵横比,这就是为什么原始形状在xml和“dp”单位中定义的原因。我确实明白Android正在使这些操作变得困难。 - Mauricio Aguilar Cardenas
1个回答

0

根据Nanoc的建议,这是一个可行的解决方案(虽然不是非常优雅但它能工作):
我是通过在xml ImageView声明中添加margin来解决的。然后你可以在Java中访问margin而不需要转换dp-pixel单位。从事件位置减去margin就可以了。
访问margin的代码:
ImageView gradient_indicator = (ImageView) findViewById(R.id.gradient_indicator); RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) gradient_indicator.getLayoutParams(); int grad_margin_top = lp.topMargin; int grad_margin_left = lp.leftMargin;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接