2015-12-03 2 views
3

Итак, я не обновляю ImageView, чтобы изменить градиенты в соответствии с некоторыми событиями от телефонного гироскопа и Lightsensor. Тем не менее, в данный момент я тестирую события кликов.android изображение view градиентный фон

Я хочу установить радиальный градиент с центром в событии клика. Сначала я попробовал установить макет с учетом этого, и все отлично поработало. Затем я попытался изменить его на 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); 
} 

А вот образ результата я получаю, я пометил положение курсора с красным кружком. Displaced Gradient

+1

Если он работал при использовании в качестве фона макета, я буду держать пари, если вы сделаете полное изображение в полноэкранном режиме, он должен работать, возможно, вам нужно компенсировать как x, y, так и позицию изображения. Вы заметили, что центр был замечен на дне при использовании в макете? – Nanoc

+0

Корень проблемы кажется маркой или дополнением, установленным в xml. Он сохраняется, если я устанавливаю маржи в самом ImageView или дополнении на Relative View, который содержит изображение. Если я принесу его в полноэкранный режим, проблем нет. Я могу решить это, вычитая пиксель поля из фактического события клика. Однако я надеялся, что это можно решить более элегантно, возможно, когда вызывается функция изменения размера шейдера. –

+0

Если вы не хотите, чтобы изображение смотрело на весь экран, это единственный способ, в IOS у вас есть функция bult-in, которая смещает touchhevent к данному виду, в Android вы должны сделать это вручную. В любом случае, все ваши проблемы вызваны тем, что вы не читаете это :) http://stackoverflow.com/questions/29956014/why-should-we-use-xml-layouts – Nanoc

ответ

0

Рабочее решение, предложенное Наноком (его не очень элегантно, но оно работает):
Способ, которым я работал, заключается в добавлении поля в объявление xml ImageView. Затем вы можете получить доступ к марже от Java без необходимости конвертировать dp-пиксельные единицы. Вычтите из позиции события и этого.
Код для доступа к полям:
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;

Смежные вопросы