private void expandTapArea(final View container, final View child) { final int padding = getResources().getDimensionPixelSize(R.dimen.contact_selection_actions_tap_area); container.post(new Runnable() { @Override public void run() { Rect rect = new Rect(); child.getHitRect(rect); rect.top -= padding; rect.left -= padding; rect.right += padding; rect.bottom += padding; container.setTouchDelegate(new TouchDelegate(rect, child)); } }); }
private void doSetTouchDelegate() { final TextView middleBtn = mMiddleButton; post(new Runnable() { @Override public void run() { Rect rect = new Rect(); rect.left = (middleBtn.getWidth() / 4); rect.right = (3 * middleBtn.getWidth() / 4); rect.top = 0; rect.bottom = middleBtn.getHeight(); middleBtn.setTouchDelegate(new TouchDelegate(rect, /* * TopBarView. * this */ mMiddleSub)); } }); }
/** * 扩展点击区域的范围 * * @param view 需要扩展的元素,此元素必需要有父级元素 * @param expendSize 需要扩展的尺寸(以sp为单位的) */ public static void expendTouchArea(final View view, final int expendSize) { if (view != null) { final View parentView = (View) view.getParent(); parentView.post(new Runnable() { @Override public void run() { Rect rect = new Rect(); view.getHitRect(rect); //如果太早执行本函数,会获取rect失败,因为此时UI界面尚未开始绘制,无法获得正确的坐标 rect.left -= expendSize; rect.top -= expendSize; rect.right += expendSize; rect.bottom += expendSize; parentView.setTouchDelegate(new TouchDelegate(rect, view)); } }); } }
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { //mTouchAreaLargerRatio float largedSize = (bottom - top) * mTouchAreaLargerRatio; int deltaY = (int) (largedSize - (bottom - top)); int deltaX = largedSize > (right - left) ? (int) (largedSize - (right - left)) : 0; ViewGroup vg = (ViewGroup) getParent(); //如果设定的半径大于固有的半径,就按设定的,如果没有大于就按固有的 Rect rect = new Rect(left - deltaX, top - deltaY, right + deltaX, bottom + deltaY); vg.setTouchDelegate(new TouchDelegate( rect, this)); } }
/** * 恢复View的触摸和点击范围,最小不小于View自身范围 * * @param view */ public void restoreViewTouchRegion(final View view) { if (view == null) { throw new RuntimeException("view cannot be null."); } final ViewGroup viewGroup = (ViewGroup) view.getParent(); if (viewGroup != null) { viewGroup.post(new Runnable() { @Override public void run() { Rect bounds = new Rect(); bounds.setEmpty(); touchDelegateGroup.addTouchDelegate(new TouchDelegate(bounds, view)); if (View.class.isInstance(viewGroup)) { viewGroup.setTouchDelegate(touchDelegateGroup); } } }); } }
/** * General-purpose function to increase the TouchDelegate size up to the minimum size * needed for accessibility, and centered around the existing center of the view. * @param viewToDelegate The view whose touchable area needs to be increased by setting a * TouchDelegate on its parent with a larger rect. */ public static void setTouchDelegateToMinAccessibleSize(final View viewToDelegate) { viewToDelegate.post(new Runnable() { @Override public void run() { if (viewToDelegate == null) { return; } int a11ySize = viewToDelegate.getContext().getResources() .getDimensionPixelSize(R.dimen.accessibility_touch_target_min_size); Rect rect = new Rect(); viewToDelegate.getHitRect(rect); resizeRect(a11ySize, rect); ((View) viewToDelegate.getParent()).setTouchDelegate(new TouchDelegate(rect, viewToDelegate)); } }); }
@BindingAdapter("increaseClickingArea") public static void increaseClickingArea(TextView textView, float size) { // fork from http://stackoverflow.com/a/1343796 View parent = (View) textView.getParent(); // post in the parent's message queue to make sure the parent // lays out its children before we call View#getHitRect() parent.post(() -> { final int halfSize = (int) (size / 2 + 0.5); Rect rect = new Rect(); textView.getHitRect(rect); rect.top -= halfSize; rect.right += halfSize; rect.bottom += halfSize; rect.left -= halfSize; // use TouchDelegate to increase count's clicking area parent.setTouchDelegate(new TouchDelegate(rect, textView)); }); }
/** * 还原View的触摸和点击响应范围,最小不小于View自身范围 */ public static void restoreViewTouchDelegate(final View view) { if (view == null) { return; } if (view.getParent() != null) { ((View) view.getParent()).postDelayed(new Runnable() { @Override public void run() { Rect bounds = new Rect(); bounds.setEmpty(); TouchDelegate touchDelegate = new TouchDelegate(bounds, view); if (View.class.isInstance(view.getParent())) { ((View) view.getParent()).setTouchDelegate(touchDelegate); } } }, 300); } }
private void setupSlidebar(View view){ SlideButton seekBar = (SlideButton) view.findViewById(R.id.lock_screen_slider); seekBar.setSlideButtonListener(new SlideButtonListener() { @Override public void handleSlide() { showUnlockScreen(); } }); // Increases the vertical touch hitbox Rect delegateArea = new Rect(); seekBar.getHitRect(delegateArea); delegateArea.top -= 600; delegateArea.bottom += 600; TouchDelegate expandedArea = new TouchDelegate(delegateArea, seekBar); if (View.class.isInstance(seekBar.getParent())) { ((View) seekBar.getParent()).setTouchDelegate(expandedArea); } }
/** * 扩大View的触摸和点击响应范围,最大不超过其父View范围 * * @param view * @param top * @param bottom * @param left * @param right */ public static void expandViewTouchDelegate(final View view, final int top, final int bottom, final int left, final int right) { ((View) view.getParent()).post(new Runnable() { @Override public void run() { Rect bounds = new Rect(); view.setEnabled(true); view.getHitRect(bounds); bounds.top -= top; bounds.bottom += bottom; bounds.left -= left; bounds.right += right; TouchDelegate touchDelegate = new TouchDelegate(bounds, view); if (View.class.isInstance(view.getParent())) { ((View) view.getParent()).setTouchDelegate(touchDelegate); } } }); }
public static void ensureMinimumTouchTargetSize(View paramView, Rect paramRect1, Rect paramRect2, int paramInt) { ViewParent localViewParent = paramView.getParent(); if (!(localViewParent instanceof View)) {} View localView; do { return; localView = (View)localViewParent; if ((paramView.getVisibility() != 0) || ((paramView.getWidth() >= paramInt) && (paramView.getHeight() >= paramInt))) { paramRect1.setEmpty(); localView.setTouchDelegate(null); return; } getTouchTarget(paramView, paramRect1, paramInt, paramInt); } while (paramRect1.equals(paramRect2)); paramRect2.set(paramRect1); localView.setTouchDelegate(new TouchDelegate(paramRect1, paramView)); }
/** * Increases the hit rect of a view. This should be used when an icon is small and cannot be easily tapped on. * Source: http://stackoverflow.com/a/1343796/5210 * @param top The amount of dp's to be added to the top for hit purposes. * @param left The amount of dp's to be added to the left for hit purposes. * @param bottom The amount of dp's to be added to the bottom for hit purposes. * @param right The amount of dp's to be added to the right for hit purposes. * @param delegate The view that needs to have its hit rect increased. */ public static void increaseHitRectBy(final int top, final int left, final int bottom, final int right, final View delegate) { final View parent = (View) delegate.getParent(); if (parent != null && delegate.getContext() != null) { parent.post(new Runnable() { // Post in the parent's message queue to make sure the parent // lays out its children before we call getHitRect() public void run() { final float densityDpi = delegate.getContext().getResources().getDisplayMetrics().densityDpi; final Rect r = new Rect(); delegate.getHitRect(r); r.top -= transformToDensityPixel(top, densityDpi); r.left -= transformToDensityPixel(left, densityDpi); r.bottom += transformToDensityPixel(bottom, densityDpi); r.right += transformToDensityPixel(right, densityDpi); parent.setTouchDelegate(new TouchDelegate(r, delegate)); } }); } }
/** * Enlarges the Touchable area of a view * @param root The root view of the param viewToExpand * @param viewToExpand The view that needs a larger touch area * @param padding The amount of padding that will be applied to the view */ public static void enlargeTouchArea(View root, final View viewToExpand, final int padding) { root.post(new Runnable() { @Override public void run() { Rect delegateArea = new Rect(); View delegate = viewToExpand; delegate.getHitRect(delegateArea); delegateArea.top -= padding; delegateArea.bottom += padding; delegateArea.left -= padding; delegateArea.right += padding; TouchDelegate expandedArea = new TouchDelegate(delegateArea, delegate); if(View.class.isInstance(delegate.getParent())){ ((View)delegate.getParent()).setTouchDelegate(expandedArea); } } }); }
private void extendTouchAreaToMatchParent(int id) { final View button = findViewById(id); final View parent = (View) button.getParent(); parent.post(new Runnable() { @Override public void run() { Rect parentRect = new Rect(); parent.getHitRect(parentRect); Rect buttonRect = new Rect(); button.getHitRect(buttonRect); int widthDiff = parentRect.width() - buttonRect.width(); int heightDiff = parentRect.height() - buttonRect.height(); buttonRect.left -= widthDiff/2; buttonRect.right += widthDiff/2; buttonRect.top -= heightDiff/2; buttonRect.bottom += heightDiff/2; parent.setTouchDelegate(new TouchDelegate(buttonRect, button)); } }); }
private void expandTapArea(final View container, final View child, final int padding) { container.post(new Runnable() { @Override public void run() { Rect rect = new Rect(); child.getHitRect(rect); rect.top -= padding; rect.left -= padding; rect.right += padding; rect.bottom += padding; container.setTouchDelegate(new TouchDelegate(rect, child)); } }); }
private void growCloseButtonHitArea() { getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(this); // Ideally we want the close button hit area to be 40x40dp but we are constrained by the height of the parent, so // we make it as tall as the parent view and 40dp across. final int targetHitArea = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, getResources().getDisplayMetrics());; final Rect hitRect = new Rect(); hitRect.top = 0; hitRect.right = getWidth(); hitRect.left = getWidth() - targetHitArea; hitRect.bottom = targetHitArea; setTouchDelegate(new TouchDelegate(hitRect, mCloseButton)); return true; } }); }
public static void expand(@NonNull final View view, final int start, final int top, final int end, final int bottom) { final View parent = (View) view.getParent(); if (parent != null) { final DisplayMetrics metrics = view.getResources().getDisplayMetrics(); parent.post(new Runnable() { @Override public void run() { parent.removeCallbacks(this); final Rect hitRect = new Rect(); hitRect.left -= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, start, metrics); hitRect.top -= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, top, metrics); hitRect.right += TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, end, metrics); hitRect.bottom += TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, bottom, metrics); view.getHitRect(hitRect); parent.setTouchDelegate(new TouchDelegate(hitRect, view)); } }); } }
/** * Increases the hit rect of a view. This should be used when an icon is small and cannot be easily tapped on. * Source: http://stackoverflow.com/a/1343796/5210 * * @param top The amount of dp's to be added to the top for hit purposes. * @param left The amount of dp's to be added to the left for hit purposes. * @param bottom The amount of dp's to be added to the bottom for hit purposes. * @param right The amount of dp's to be added to the right for hit purposes. */ public T increaseHitRect(final int top, final int left, final int bottom, final int right) { final View parent = (View) view.getParent(); if (parent != null && view.getContext() != null) { parent.post(new Runnable() { // Post in the parent's message queue to make sure the parent // lays out its children before we call getHitRect() public void run() { final Rect r = new Rect(); view.getHitRect(r); r.top -= dip2pixel(top); r.left -= dip2pixel(left); r.bottom += dip2pixel(bottom); r.right += dip2pixel(right); parent.setTouchDelegate(new TouchDelegate(r, view)); } }); } return self(); }
/** * Increase the touch area of child view in its parent view with the given dimensions. * * @param parentView * container of child view * @param childView * child view to increase touch area * @param left * to increasing left size * @param top * to increasing top size * @param right * to increasing right size * @param bottom * to increasing bottom size */ public static void increaseTouchArea(final View parentView, final View childView, final int left, final int top, final int right, final int bottom) { parentView.post(new Runnable() { @Override public void run() { Rect delegateArea = new Rect(); childView.getHitRect(delegateArea); delegateArea.left += left; delegateArea.top += top; delegateArea.right += right; delegateArea.bottom += bottom; TouchDelegate touchDelegate = new TouchDelegate(delegateArea, childView); if (childView.getParent() instanceof View) { ((View) childView.getParent()) .setTouchDelegate(touchDelegate); } } }); }
/** * Increases the hit rect of a view. This should be used when an icon is small and cannot be easily tapped on. * Source: http://stackoverflow.com/a/1343796/5210 * * @param top The amount of dp's to be added to the top for hit purposes. * @param left The amount of dp's to be added to the left for hit purposes. * @param bottom The amount of dp's to be added to the bottom for hit purposes. * @param right The amount of dp's to be added to the right for hit purposes. * @param delegate The view that needs to have its hit rect increased. */ public static void increaseHitRectBy(final int top, final int left, final int bottom, final int right, final View delegate) { final View parent = (View) delegate.getParent(); if (parent != null && delegate.getContext() != null) { parent.post(new Runnable() { // Post in the parent's message queue to make sure the parent // lays out its children before we call getHitRect() public void run() { final float densityDpi = delegate.getContext().getResources().getDisplayMetrics().densityDpi; final Rect r = new Rect(); delegate.getHitRect(r); r.top -= transformToDensityPixel(top, densityDpi); r.left -= transformToDensityPixel(left, densityDpi); r.bottom += transformToDensityPixel(bottom, densityDpi); r.right += transformToDensityPixel(right, densityDpi); parent.setTouchDelegate(new TouchDelegate(r, delegate)); } }); } }
@Override protected void onBindView(View view) { super.onBindView(view); mSpinner = (Spinner) view.findViewById(R.id.spinnerWidget); final ViewParent parent = mSpinner.getParent(); if(parent instanceof View) { final Rect rect = new Rect(0, 0, ((View) parent).getWidth(), ((View) parent).getHeight()); ((View) parent).setTouchDelegate(new TouchDelegate(rect, (View) parent)); } updateSpinner(); mSpinner.setOnItemSelectedListener(this); }
public static Runnable getTouchDelegateAction(final View parent, final View delegate, final int topPadding, final int bottomPadding, final int leftPadding, final int rightPadding) { return new Runnable() { public void run() { //Construct a new Rectangle and let the Delegate set its values Rect touchRect = new Rect(); delegate.getHitRect(touchRect); //Modify the dimensions of the Rectangle //Padding values below zero are replaced by zeros touchRect.top-=Math.max(0, topPadding); touchRect.bottom+=Math.max(0, bottomPadding); touchRect.left-=Math.max(0, leftPadding); touchRect.right+=Math.max(0, rightPadding); //Now we are going to construct the TouchDelegate TouchDelegate touchDelegate = new TouchDelegate(touchRect, delegate); //And set it on the parent parent.setTouchDelegate(touchDelegate); } }; }
@Override public boolean onTouchEvent(@NonNull MotionEvent event) { if (!mEnabled) return false; TouchDelegate delegate = null; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: for (int i = 0; i < mTouchDelegates.size(); i++) { TouchDelegate touchDelegate = mTouchDelegates.get(i); if (touchDelegate.onTouchEvent(event)) { mCurrentTouchDelegate = touchDelegate; return true; } } break; case MotionEvent.ACTION_MOVE: delegate = mCurrentTouchDelegate; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: delegate = mCurrentTouchDelegate; mCurrentTouchDelegate = null; break; default: // Do Nothing break; } return delegate != null && delegate.onTouchEvent(event); }
@Override public boolean onTouchEvent(@NonNull MotionEvent event) { if (!mEnabled) return false; TouchDelegate delegate = null; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: for (int i = 0; i < mTouchDelegates.size(); i++) { TouchDelegate touchDelegate = mTouchDelegates.get(i); if (touchDelegate.onTouchEvent(event)) { mCurrentTouchDelegate = touchDelegate; return true; } } break; case MotionEvent.ACTION_MOVE: delegate = mCurrentTouchDelegate; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: delegate = mCurrentTouchDelegate; mCurrentTouchDelegate = null; break; } return delegate != null && delegate.onTouchEvent(event); }
@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); delegateContainer = (TouchDelegateViewGroup) view.findViewById(R.id.delegate_container); rtn = (RadioButton) view.findViewById(R.id.rtn); Rect rect = new Rect(500, 500, 800, 800); delegateContainer.setDelegateAreaColor(Color.RED, rect); delegateContainer.setTouchDelegate(new TouchDelegate(rect, rtn)); return view; }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //Log.d(this + " onCreateView startet efter " + (System.currentTimeMillis() - App.opstartstidspunkt) + " ms"); String kanalkode = getArguments().getString(P_KANALKODE); kanal = App.grunddata.kanalFraKode.get(kanalkode); rod = inflater.inflate(R.layout.kanal_nyheder_frag, container, false); aq = new AQuery(rod); aq.id(R.id.hør_live).typeface(App.skrift_gibson).clicked(this); // Knappen er meget vigtig, og har derfor et udvidet område hvor det også er den man rammer // se http://developer.android.com/reference/android/view/TouchDelegate.html final int udvid = getResources().getDimensionPixelSize(R.dimen.hørknap_udvidet_klikområde); final View hør = aq.id(R.id.hør_live).getView(); hør.post(new Runnable() { @Override public void run() { Rect r = new Rect(); hør.getHitRect(r); r.top -= udvid; r.bottom += udvid; r.right += udvid; r.left -= udvid; //Log.d("hør_udvidet_klikområde=" + r); ((View) hør.getParent()).setTouchDelegate(new TouchDelegate(r, hør)); } }); aq.id(R.id.titel).typeface(App.skrift_gibson); App.afspiller.observatører.add(this); App.netværk.observatører.add(this); //Log.d(this + " onCreateView færdig efter " + (System.currentTimeMillis() - App.opstartstidspunkt) + " ms"); return rod; }
/** * 扩大View的触摸和点击范围,最大不超过其父View范围 * * @param view * @param top * @param bottom * @param left * @param right */ public void expandViewTouchRegion(final View view, final int left, final int top, final int right , final int bottom) { if (view == null) { throw new RuntimeException("view cannot be null."); } final ViewGroup viewGroup = (ViewGroup) view.getParent(); if (viewGroup != null) { viewGroup.post(new Runnable() { @Override public void run() { Rect bounds = new Rect(); view.setEnabled(true); view.getHitRect(bounds); bounds.left -= left; bounds.top -= top; bounds.right += right; bounds.bottom += bottom; // touchDelegateGroup.clearTouchDelegates(); touchDelegateGroup.addTouchDelegate(new TouchDelegate(bounds, view)); if (View.class.isInstance(viewGroup)) { viewGroup.setTouchDelegate(touchDelegateGroup); } } }); } }
public void removeTouchDelegate(TouchDelegate touchDelegate) { if (mTouchDelegates != null) { mTouchDelegates.remove(touchDelegate); if (mTouchDelegates.isEmpty()) { mTouchDelegates = null; } } }