How it looks
I want to check intersection between ImageView to ImageView2 as LinearLayout slides towards ImageView2.
I used Rect but it is not working, ImageView2 Just passed throught it without getting intersect.
Please help me!!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<ImageView
android:id="#+id/tile"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/tile" />
<LinearLayout
android:id="#+id/l1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageView
android:id="#+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
<ImageView
android:id="#+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
</LinearLayout>
#SuppressLint("NewApi")
public class MainActivity extends Activity {
Rect tileRect = new Rect();
Rect b1Rect = new Rect();
Rect b2Rect = new Rect();
ImageView tile,b1,b2;
RelativeLayout layout;
LinearLayout l1;
final Handler h = new Handler();
Boolean tileRight=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
move();
}
private void init() {
// TODO Auto-generated method stub
b1 = (ImageView)findViewById(R.id.b1);
b2 = (ImageView)findViewById(R.id.b2);
tile = (ImageView)findViewById(R.id.tile);
layout = (RelativeLayout)findViewById(R.id.layout);
l1 = (LinearLayout)findViewById(R.id.l1);
tile.setX(320);
tile.setY(800);
l1.setVisibility(View.VISIBLE);
}
public void move()
{
final int delay = 45;
h.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(tileRight==true)
tileRight=false;
else
tileRight=true;
return true;
}
return false;
}
});
if(tileRight==true)
{
if(tile.getX()>600f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()+speedTile);
}
}
else{
if(tile.getX()<40f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()-speedTile);
}
}
tile.getHitRect(tileRect);
b1.getHitRect(b1Rect);
b2.getHitRect(b2Rect);
if(Rect.intersects(tileRect, b1Rect) || Rect.intersects(tileRect, b2Rect))
{
gameOver();
}
l1.setY(l1.getY()+10f);
h.postDelayed(this, delay);
}
},delay);
}
private void gameOver() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android's View has getLocationOnScreen() method that shows absolute position of your view.
https://developer.android.com/reference/android/view/View.html#getLocationOnScreen(int[])
The issue occurs because view.getHitRect() is used before the layouts are inflated.
Any of the view's position or measurement APIs like getWidth(), getTop(), getRight() etc. will return 0 (getHitRect() initializes the Rect with (0,0,0,0)) in onCreate() or onResume() before the views are inflated.
In your case, it appears that the Handler's delay period executes the intersection logic earlier than view inflation.
You could post from the view and the run() method will execute after the view inflates and then obtain the view's measurement parameters or a Rect .
Here is an example:
public class MyTestActivity extends AppCompatActivity{
int mNumberOfViewsInitialized = 0;
ImageView mImageViewRight, mImageViewLeft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_image_activity);
mImageViewLeft = (ImageView) findViewById(R.id.image_view_left);
mImageViewRight = (ImageView) findViewById(R.id.image_view_right);
// calling method here will log that the views do not intersect
// which happens because they haven't been inflated yet.
// doViewsOverlap();
mImageViewLeft.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
mImageViewRight.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
}
private void intersectionLogic(){
/* the constant could be something else, depending
on the number of views you'd like to test intersection for*/
if(mNumberOfViewsInitialized == 2){
doViewsOverlap(mImageViewLeft,mImageViewRight);
}
}
private void doViewsOverlap(final View firstView, final View secondView){
Rect leftRect = new Rect();
firstView.getHitRect(leftRect);
Rect rightRect = new Rect();
secondView.getHitRect(rightRect);
if(Rect.intersects(leftRect,rightRect) || Rect.intersects(rightRect,leftRect))
Log.v("intersects","views intersect");
else
Log.v("intersects","views do not intersect");
}
}
I used a layout which does not animate / move the images, but the same issue should occur when the images are moved as well
<ImageView
android:id="#+id/image_view_left"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:background="#android:color/holo_blue_dark"
android:src = "#mipmap/ic_launcher"/>
<ImageView
android:id="#+id/image_view_right"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentRight="true"
android:background="#android:color/holo_green_dark"
android:gravity="end"
android:src="#mipmap/ic_launcher"/>
Images contained in a RelativeLayout.
Here is a screenshot of the UI:
This problem is related to this: If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Hope this helps.
Related
I am creating SlidingPanelLayout from right to left for the filter purpose.The panel work fine it come out from right side and does animation but when Animation is stop it directly go to left side full but I want the ratio is 70% means right side panel came out 70% of the total screen and when click again it goes to hind and full Activity is display.
When first time Animation is stop the side panel goes to left side in the screenshot .But I want it right side.
ScreenShot :
but i want to display it write side and when click again it will go right side and hide again.
activity_inventory.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e6e6e6"
android:id="#+id/mainLayout"
tools:context="com.example.softeng.jogi.InventoryActivity">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/backLayout"
tools:ignore="NotSibling">
</RelativeLayout>
<include
layout="#layout/filter"/>
<com.rey.material.widget.FloatingActionButton
android:id="#+id/button_bt_float_wave_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
style="#style/LightFABWaveColor"
android:layout_margin="8dp"/>
</RelativeLayout>
filter.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/filter_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0072BA"
android:visibility="invisible">
</RelativeLayout>
</RelativeLayout>
filterAnimation.java
public class FilterAnimation implements Animation.AnimationListener
{
Context context;
RelativeLayout filterLayout, otherLayout;
private Animation filterSlideIn, filterSlideOut, otherSlideIn, otherSlideOut;
private static int otherLayoutWidth, otherLayoutHeight;
private boolean isOtherSlideOut = false;
private int deviceWidth;
private int margin;
public FilterAnimation(Context context)
{
this.context = context;
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
deviceWidth = displayMetrics.widthPixels; // as my animation is x-axis related so i gets the device width and will use that width,so that this sliding menu will work fine in all screen resolutions
}
public void initializeFilterAnimations(RelativeLayout filterLayout)
{
this.filterLayout = filterLayout;
filterSlideIn = AnimationUtils.loadAnimation(context, R.anim.filter_slide_in);
filterSlideOut = AnimationUtils.loadAnimation(context, R.anim.filter_slide_out);
}
public void initializeOtherAnimations(RelativeLayout otherLayout)
{
this.otherLayout = otherLayout;
otherLayoutWidth = otherLayout.getWidth();
otherLayoutHeight = otherLayout.getHeight();
otherSlideIn = AnimationUtils.loadAnimation(context, R.anim.other_slide_in);
otherSlideIn.setAnimationListener(this);
otherSlideOut = AnimationUtils.loadAnimation(context, R.anim.other_slide_out);
otherSlideOut.setAnimationListener(this);
}
public void toggleSliding()
{
if(isOtherSlideOut) //check if findLayout is already slided out so get so animate it back to initial position
{
filterLayout.startAnimation(filterSlideOut);
filterLayout.setVisibility(View.INVISIBLE);
otherLayout.startAnimation(otherSlideIn);
}
else //slide findLayout Out and filterLayout In
{
otherLayout.startAnimation(otherSlideOut);
filterLayout.setVisibility(View.VISIBLE);
filterLayout.startAnimation(filterSlideIn);
}
}
#Override
public void onAnimationEnd(Animation animation)
{
if(isOtherSlideOut) //Now here we will actually move our view to the new position,because animations just move the pixels not the view
{
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(otherLayoutWidth, otherLayoutHeight);
otherLayout.setLayoutParams(params);
isOtherSlideOut = false;
}
else
{
margin = (deviceWidth * 70) / 100; //here im coverting device percentage width into pixels, in my other_slide_in.xml or other_slide_out.xml you can see that i have set the android:toXDelta="80%",so it means the layout will move to 80% of the device screen,to work across all screens i have converted percentage width into pixels and then used it
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(otherLayoutWidth, otherLayoutHeight);
params.leftMargin = margin;
params.rightMargin = -margin; //same margin from right side (negavite) so that our layout won't get shrink
otherLayout.setLayoutParams(params);
isOtherSlideOut = true;
dimOtherLayout();
}
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationStart(Animation animation)
{
}
private void dimOtherLayout()
{
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);
alphaAnimation.setFillAfter(true);
otherLayout.startAnimation(alphaAnimation);
}
}
InventoryActivity.java
public class InventoryActivity extends AppCompatActivity implements View.OnClickListener {
RelativeLayout filterLayout, findLayout;
FilterAnimation filterAnimation;
FloatingActionButton bffilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inventory);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
filterLayout = (RelativeLayout)findViewById(R.id.filter_layout);
findLayout = (RelativeLayout)findViewById(R.id.backLayout);
bffilter = (FloatingActionButton)findViewById(R.id.button_bt_float_wave_color);
bffilter.setOnClickListener(this);
filterAnimation = new FilterAnimation(this);
initializeAnimations();
}
private void initializeAnimations(){
final ViewTreeObserver filterObserver = filterLayout.getViewTreeObserver();
filterObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
filterLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int deviceWidth = displayMetrics.widthPixels;
int filterLayoutWidth = (deviceWidth * 70) / 100;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(filterLayoutWidth, RelativeLayout.LayoutParams.MATCH_PARENT);
filterLayout.setLayoutParams(params);
filterAnimation.initializeFilterAnimations(filterLayout);
}
});
final ViewTreeObserver findObserver = findLayout.getViewTreeObserver();
findObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
findLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
filterAnimation.initializeOtherAnimations(findLayout);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_inventory, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == android.R.id.home) {
this.finish();
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.button_bt_float_wave_color:
filterAnimation.toggleSliding();
break;
}
}
}
filter_slide_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromXDelta="130%"
android:toXDelta="30%"
android:duration="1000" />
</set>
filter_slide_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromXDelta="30%"
android:toXDelta="130%"
android:duration="1000"/>
</set>
other_slide_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromXDelta="-70%"
android:toXDelta="30%"
android:duration="1000"
android:fillEnabled="true"/>
</set>
other_slide_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator" >
<translate
android:fromXDelta="30%"
android:toXDelta="-70%"
android:duration="1000"/>
</set>
My Question : How I want to set right side panel to display and when click again it goes away. simply I my this code I want to remove the panel goes to full left see in the screenshot. the other part working fine.
ScreenShot :
Thanks in Advance.
I think I found the Solution. I am Creating the new Project.
Sliding.java
public class Sliding extends LinearLayout
{
private Paint innerPaint, borderPaint ;
public Sliding(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Sliding(Context context) {
super(context);
init();
}
private void init() {
innerPaint = new Paint();
innerPaint.setARGB(0, 255, 255, 255); //gray
innerPaint.setAntiAlias(true);
borderPaint = new Paint();
borderPaint.setARGB(255, 255, 255, 255);
borderPaint.setAntiAlias(true);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(2);
}
public void setInnerPaint(Paint innerPaint) {
this.innerPaint = innerPaint;
}
public void setBorderPaint(Paint borderPaint) {
this.borderPaint = borderPaint;
}
#Override
protected void dispatchDraw(Canvas canvas) {
RectF drawRect = new RectF();
drawRect.set(0,0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(drawRect, 5, 5, innerPaint);
canvas.drawRoundRect(drawRect, 5, 5, borderPaint);
super.dispatchDraw(canvas);
}
}
Sliding2Activity.java
public class Sliding2Activity extends Activity {
CheckBox c1,c2,c3;
int key=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sliding2);
final Sliding popup = (Sliding) findViewById(R.id.sliding1);
popup.setVisibility(View.GONE);
final FloatingActionButton btn=(FloatingActionButton)findViewById(R.id.show1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (key == 0) {
key = 1;
popup.setVisibility(View.VISIBLE);
} else if (key == 1) {
key = 0;
popup.setVisibility(View.GONE);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_sliding2, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
activity_sliding2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="right"
android:orientation="horizontal">
<com.rey.material.widget.FloatingActionButton
android:id="#+id/show1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
style="#style/LightFABWaveColor"
android:layout_margin="8dp"
android:layout_gravity="bottom" />
<com.example.softeng.panel.Sliding
android:id="#+id/sliding1"
android:layout_width="250dp"
android:layout_height="match_parent"
android:background="#0072BA"
android:gravity="left"
android:orientation="vertical"
android:padding="1px">
<CheckBox
android:id="#+id/check1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option1"
android:textColor="#FFFFFF" />
<CheckBox
android:id="#+id/check2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option2"
android:textColor="#FFFFFF" />
<CheckBox
android:id="#+id/check3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option3"
android:textColor="#FFFFFF" />
</com.example.softeng.panel.Sliding>
</LinearLayout>
ScreenShot :
Normal screen when Activity is running.
When Click on FloatinActionButton. The layout is change.
When you click again the output is screen one.
I am working on images, I am going to display image in full screen, as user touches on screen then some controls will be shown. So I want to disable zooming when controls are on the screen.
Or somebody tell me how to detect the image is zoom or not?
activity_image.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="#+id/imgSelected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="centerInside"
android:src="#drawable/placeholder"
android:contentDescription="#string/image" />
<LinearLayout
android:id="#+id/imageControls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:weightSum="9"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="horizontal"
android:visibility="gone"
android:background="#drawable/image_controls">
<Button
android:id="#+id/btnSetAsBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="left|center_vertical"
android:background="#00000000"
style="#style/ImageControls"
android:text="Set"/>
<Button
android:id="#+id/btnFavorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#00000000"
style="#style/ImageControls"
android:text="Favourite"/>
<Button
android:id="#+id/btnShare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="right|center_vertical"
android:background="#00000000"
style="#style/ImageControls"
android:text="Share"/>
</LinearLayout>
</RelativeLayout>
activity_zoom.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" >
</LinearLayout>
ImageActivity.java
public class ImageActivity extends Activity {
private int imageId;
private int categoryId;
private String imageUrl;
private ZoomView zoomView;
private ImageView imageView;
private LinearLayout main_container;
private boolean controlFlag;
private LinearLayout imageControls;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zoom);
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
final View convertView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.activity_image, null, false);
convertView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
imageControls = (LinearLayout) convertView.findViewById(R.id.imageControls);
controlFlag = false;
zoomView = new ZoomView(this);
imageId = getIntent().getExtras().getInt("image");
categoryId = getIntent().getExtras().getInt("category");
imageView = (ImageView) convertView.findViewById(R.id.imgSelected);
imageUrl = SplashActivity.urlList.get(categoryId).get(imageId);
Log.e(String.valueOf(categoryId),imageUrl);
Picasso
.with(this)
.load(imageUrl)
.placeholder(R.drawable.placeholder)
.into(imageView, new Callback() {
#Override
public void onError() {
}
#Override
public void onSuccess() {
imageView.setScaleType(ScaleType.FIT_CENTER);
}
});
zoomView.addView(convertView);
main_container = (LinearLayout) findViewById(R.id.main_container);
main_container.addView(zoomView);
convertView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if(controlFlag) {
imageControls.setVisibility(View.GONE);
controlFlag = false;
} else {
imageControls.setVisibility(View.VISIBLE);
controlFlag = true;
}
return false;
}
});
}
}
I am using android-zoom-view.jar library for zooming. I want to display LinearLayout (imageControls) only if image is not zoom Or disable zooming if LinearLayout (imageControls) is visible. Because ZoomView instance perform zooming on all over activity so the imageControls will also be zoom. This is not a good user friendly design.
So please help me to make this layout better.
Thanks...
In zoomview class thinking you using this https://github.com/Polidea/android-zoom-view/blob/master/src/pl/polidea/view/ZoomView.java
just add this
boolean isZoomEnable= true;
public void setIsZoomEnable(boolean value){
isZoomEnable = value;
}
#Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
if(!isZoomEnable) return false;
// single touch
if (ev.getPointerCount() == 1) {
processSingleTouchEvent(ev);
}
// // double touch
if (ev.getPointerCount() == 2) {
processDoubleTouchEvent(ev);
}
// redraw
getRootView().invalidate();
invalidate();
return true;
}
Then in your code
convertView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if(controlFlag) {
imageControls.setVisibility(View.GONE);
controlFlag = false;
} else {
imageControls.setVisibility(View.VISIBLE);
controlFlag = true;
}
zoomView.setIsZoomEnable(!controlFlag);
return false;
}
});
I have an Activity with some elements like ImageView, Button, ToggleButton, ... . And a subview (LinearLayout) that contains an HorizontalScrollView of ImageView.
The subview is an element that I want to hide / show with an animation.
My animation works successfully. But when I touch a ToggleButton or I apply a Filter, the subview is reseted and back to its origin position.
I have deduce that the subview is replaced in its origin when an element of the view visually change.
But I don't understand why...
The Activity class
public class CameraActivity extends Activity implements PictureCallback
{
private ToggleButton flashButton;
private Button filterScrollButton;
private LinearLayout filterScrollView;
private LinearLayout filterScrollViewLayout;
private Boolean filtersIsOpened = false;
private ImageView filterImageView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
flashButton = (ToggleButton)findViewById(R.id.button_flash);
filterScrollButton = (Button)findViewById(R.id.button_open_filters);
filterScrollView = (LinearLayout)findViewById(R.id.camera_scroll_filters);
filterScrollViewLayout = (LinearLayout)findViewById(R.id.camera_scroll_filters_layout);
}
...
private void initScrollFilters()
{
String[] filters = getResources().getStringArray(R.array.array_filters);
for (final String string : filters)
{
ImageView v = new ImageView(CameraActivity.this);
int imageFilterId = -1;
if (string != null && !string.isEmpty())
{
final int imageId = getResources().getIdentifier("#drawable/filter_" + string, null, getPackageName());
imageFilterId = getResources().getIdentifier("#drawable/filter_" + string, null, getPackageName());
v.setImageDrawable(getResources().getDrawable(imageId));
}
final int finalImageFilterId = imageFilterId;
v.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view) {
Log.d(string + " filter image is touched");
CameraActivity.this.cameraManager.setImageFilter(finalImageFilterId); // Apply the new filter into filterImageView
}
});
filterScrollViewLayout.addView(v, 100, 100);
}
}
private void initListeners()
{
// Flash
flashButton.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// camera parameters is changed
}
});
// Filter scroll view
filterScrollButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
Log.d("You click the filter scroll button men!!");
final float direction = (CameraActivity.this.filtersIsOpened) ? -1 : 1;
final float yDelta = -100;
final Animation animation = new TranslateAnimation(0, 0, 0, yDelta * direction);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation)
{
TranslateAnimation anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
anim.setDuration(1);
CameraActivity.this.filterScrollView.startAnimation(anim);
int top = (int) (CameraActivity.this.filterScrollView.getTop() + (yDelta * direction));
CameraActivity.this.filterScrollView.setTop(top);
}
});
animation.setDuration(500);
CameraActivity.this.filterScrollView.startAnimation(animation);
CameraActivity.this.filtersIsOpened = ! CameraActivity.this.filtersIsOpened;
}
});
}
...
}
The xml view
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CameraActivity" >
<CameraPreview
android:id="#+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/camera_preview_filter"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:rotation="90"
android:scaleType="center"
android:contentDescription="#string/content_desc_overlay" />
<LinearLayout
android:id="#+id/camera_scroll_filters"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="-40dp"
android:paddingTop="40dp"
android:orientation="vertical"
android:clickable="false"
android:longClickable="false" >
<Button
android:id="#+id/button_open_filters"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:layout_gravity="top|center_horizontal"
android:text="Filters" >
</Button>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF00FF00"
android:scrollbars="none" >
<LinearLayout
android:id="#+id/camera_scroll_filters_layout"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_gravity="bottom"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
android:background="#FF000000" >
</FrameLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:onClick="onCaptureClick"
android:text="#string/button_capture_text" />
</FrameLayout>
So I'm realy confused
I am having a View(R.layout.main) which includes a custom view (canvas)
this View contains a button which is overlayed over the canvas
but when I click the button the OnClicklistener fires the event but after that button is doing nothing when clicked
Activity :
public class RunActivity extends Activity implements OnTouchListener, OnClickListener {
static int width;
static int height;
static boolean reset=false;
//draw d;
View d;
Button jump_button;
//jump
float last_touchpos=0;
static boolean jump=false;
private static Context mContext;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//d = new draw(this);
d = getLayoutInflater().inflate(R.layout.main, null);
d.setOnTouchListener(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mContext = this;
//get screen size
WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
width = display.getWidth(); // deprecated
height = display.getHeight(); // deprecated
setContentView(d);
jump_button = (Button) findViewById(R.id.jump);
jump_button.setOnClickListener(this);
}
public static Context getContext(){
return mContext;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("touch","touched");
if (draw.end == true)
{
reset=true;
}
else
{
if(last_touchpos != 0)
{
if(last_touchpos < event.getY())
{
jump = true;
last_touchpos = 0;
}
}
else
{
last_touchpos = event.getY();
}
}
return false;
}
#Override
public void onClick(View arg0) {
jump = true;
}
}
Layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<run.alexander.fuchs.draw
android:id="#+id/canvasview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/jump"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Jump" />
</RelativeLayout>
static boolean jump=false;
remove static from this statement
boolean jump=false;
How can you sure your onClick is called once. Use a log print message within onClick method to make sure that it is called once. Your code is okay, and I hope your onClick works properly and check your rest of code.
I want to implement a slider, which is basically two lines, one vertical and one horizontal, crossing where the screen is touched. I have managed to make one but I have to issues:
The slider is not very smooth, there is a slight delay when I'm moving the finger
If I place two sliders it is not multitouch, and I'd like to use both of them simultaneously
Here is the code:
public class Slider extends View {
private Controller controller = new Controller();
private boolean initialisedSlider;
private int sliderWidth, sliderHeight;
private Point pointStart;
private Paint white;
private int mode;
final static int VERTICAL = 0, HORIZONTAL = 1, BOTH = 2;
public Slider(Context context) {
super(context);
setFocusable(true);
// TODO Auto-generated constructor stub
}
public Slider(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
pointStart = new Point();
initialisedSlider = false;
mode = Slider.BOTH;
}
#Override
protected void onDraw(Canvas canvas) {
if(!initialisedSlider) {
initialisedSlider = true;
sliderWidth = getMeasuredWidth();
sliderHeight = getMeasuredHeight();
pointStart.x = (int)(sliderWidth/2.0);
pointStart.y = (int)(sliderHeight/2.0);
controller = new Controller(pointStart, 3);
white = new Paint();
white.setColor(0xFFFFFFFF);
}
canvas.drawLine(controller.getCoordX(),0,
controller.getCoordX(),sliderHeight,
white);
canvas.drawLine(0, controller.getCoordY(),
sliderWidth, controller.getCoordY(),
white);
}
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
case MotionEvent.ACTION_MOVE:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
case MotionEvent.ACTION_UP:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
}
invalidate();
return true;
}
private boolean isInBounds(int x, int y) {
return ((x<=(sliderWidth)) && (x>=(0))
&& (y<=(sliderHeight)) && (y>=(0)));
}
private void updateController(int x, int y) {
switch(mode) {
case Slider.HORIZONTAL:
controller.setCoordX(x);
break;
case Slider.VERTICAL:
controller.setCoordY(y);
break;
case Slider.BOTH:
controller.setCoordX(x);
controller.setCoordY(y);
break;
}
}
private class Controller {
private int coordX, coordY;
Controller() {
}
Controller(Point point, int width) {
setCoordX(point.x);
setCoordY(point.y);
}
public void setCoordX(int coordX) {
this.coordX = coordX;
}
public int getCoordX() {
return coordX;
}
public void setCoordY(int coordY) {
this.coordY = coordY;
}
public int getCoordY() {
return coordY;
}
}
}
And the XML file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
</LinearLayout>
How to implement a SeekBar
Add the SeekBar to your layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<SeekBar
android:id="#+id/seekBar"
android:max="100"
android:progress="50"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Notes
max is the highest value that the seek bar can go to. The default is 100. The minimum is 0. The xml min value is only available from API 26, but you can just programmatically convert the 0-100 range to whatever you need for earlier versions.
progress is the initial position of the slider dot (called a "thumb").
For a vertical SeekBar use android:rotation="270".
Listen for changes in code
public class MainActivity extends AppCompatActivity {
TextView tvProgressLabel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// set a change listener on the SeekBar
SeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
int progress = seekBar.getProgress();
tvProgressLabel = findViewById(R.id.textView);
tvProgressLabel.setText("Progress: " + progress);
}
SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// updated continuously as the user slides the thumb
tvProgressLabel.setText("Progress: " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// called when the user first touches the SeekBar
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// called after the user finishes moving the SeekBar
}
};
}
Notes
If you don't need to do any updates while the user is moving the seekbar, then you can just update the UI in onStopTrackingTouch.
See also
SeekBar Tutorial With Example In Android Studio
Android provides slider which is horizontal
http://developer.android.com/reference/android/widget/SeekBar.html
and implement OnSeekBarChangeListener
http://developer.android.com/reference/android/widget/SeekBar.OnSeekBarChangeListener.html
If you want vertical Seekbar then follow this link
http://hoodaandroid.blogspot.in/2012/10/vertical-seek-bar-or-slider-in-android.html
For future readers!
Starting from material components android 1.2.0-alpha01, you have slider component
ex:
<com.google.android.material.slider.Slider
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="20f"
android:valueTo="70f"
android:stepSize="10" />
Release notes
Material Design Spec
Docs