@Override public void setRemoveClippedSubviews(boolean removeClippedSubviews) { if (removeClippedSubviews == mRemoveClippedSubviews) { return; } mRemoveClippedSubviews = removeClippedSubviews; if (removeClippedSubviews) { mClippingRect = new Rect(); ReactClippingViewGroupHelper.calculateClippingRect(this, mClippingRect); mAllChildrenCount = getChildCount(); int initialSize = Math.max(12, mAllChildrenCount); mAllChildren = new View[initialSize]; mChildrenLayoutChangeListener = new ChildrenLayoutChangeListener(this); for (int i = 0; i < mAllChildrenCount; i++) { View child = getChildAt(i); mAllChildren[i] = child; child.addOnLayoutChangeListener(mChildrenLayoutChangeListener); } updateClippingRect(); } else { // Add all clipped views back, deallocate additional arrays, remove layoutChangeListener Assertions.assertNotNull(mClippingRect); Assertions.assertNotNull(mAllChildren); Assertions.assertNotNull(mChildrenLayoutChangeListener); for (int i = 0; i < mAllChildrenCount; i++) { mAllChildren[i].removeOnLayoutChangeListener(mChildrenLayoutChangeListener); } getDrawingRect(mClippingRect); updateClippingToRect(mClippingRect); mAllChildren = null; mClippingRect = null; mAllChildrenCount = 0; mChildrenLayoutChangeListener = null; } }
/*package*/ void addViewWithSubviewClippingEnabled(View child, int index, LayoutParams params) { Assertions.assertCondition(mRemoveClippedSubviews); Assertions.assertNotNull(mClippingRect); Assertions.assertNotNull(mAllChildren); addInArray(child, index); // we add view as "clipped" and then run {@link #updateSubviewClipStatus} to conditionally // attach it int clippedSoFar = 0; for (int i = 0; i < index; i++) { if (mAllChildren[i].getParent() == null) { clippedSoFar++; } } updateSubviewClipStatus(mClippingRect, index, clippedSoFar); child.addOnLayoutChangeListener(mChildrenLayoutChangeListener); }
/** * Set the view that acts as the anchor for the control view. This can for example be a VideoView, * or your Activity's main view. * * @param view The view to which to anchor the controller when it is visible. */ public void setAnchorView(View view) { if (mAnchor != null) { mAnchor.removeOnLayoutChangeListener(mLayoutChangeListener); } mAnchor = view; if (mAnchor != null) { mAnchor.addOnLayoutChangeListener(mLayoutChangeListener); } FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); removeAllViews(); View v = makeControllerView(); addView(v, frameParams); }
@Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mRootView = inflater .cloneInContext(new ContextThemeWrapper(getContext(), getTheme())) .inflate(R.layout.fragment_side, container, false); final Bundle args = getArguments(); if (args != null) { mRootView.addOnLayoutChangeListener( new View.OnLayoutChangeListener() { @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { v.removeOnLayoutChangeListener(this); int cx = args.getInt("cx"); int cy = args.getInt("cy"); // get the hypothenuse so the mRadius is from one corner to the other float radius = (float) Math.hypot(right, bottom); // Hardware-supported clipPath() // http://developer.android.com/guide/topics/graphics/hardware-accel.html if (Build.VERSION.SDK_INT >= 18) { Animator reveal = createCheckoutRevealAnimator((ClipRevealFrame) v, cx, cy, 28f, radius); reveal.start(); } else { removeOldSideFragment(); } } }); } ButterKnife.bind(this, mRootView); return mRootView; }
private void attachKeyboardVisibilityListener() { View keyboardVisibilityDetector = findViewById(R.id.resize_detector); keyboardVisibilityDetector.addOnLayoutChangeListener( new OnLayoutChangeListener() { // Tracks the maximum 'bottom' value seen during layout changes. This value represents // the top of the SystemUI displayed at the bottom of the screen. // Note: This value is a screen coordinate so a larger value means lower on the screen. private int mMaxBottomValue; @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { // As the activity is started, a number of layout changes will flow through. If // this is a fresh start, then we will see one layout change which will represent // the steady state of the UI and will include an accurate 'bottom' value. If we // are transitioning from another activity/orientation, then there may be several // layout change events as the view is updated (i.e. the OSK might have been // displayed previously but is being dismissed). Therefore we want to track the // largest value we have seen and use it to determine if a new system UI (such as // the OSK) is being displayed. if (mMaxBottomValue < bottom) { mMaxBottomValue = bottom; return; } // If the delta between lowest bound we have seen (should be a systemUI such as // the navigation bar) and the current bound does not match, then we have a form // of soft input displayed. Note that the size of a soft input device can change // when the input method is changed so we want to send updates to the image canvas // whenever they occur. mSoftInputVisible = (bottom < mMaxBottomValue); mRemoteHostDesktop.onSoftInputMethodVisibilityChanged( mSoftInputVisible, new Rect(left, top, right, bottom)); } }); }
private static void centerViewVertically(View view) { view.addOnLayoutChangeListener( new View.OnLayoutChangeListener() { @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { v.setTranslationY(-v.getHeight() / 2); v.removeOnLayoutChangeListener(this); } }); }
@Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_sign_in, container, false); view.addOnLayoutChangeListener( new View.OnLayoutChangeListener() { @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { v.removeOnLayoutChangeListener(this); setUpGridView(getView()); } }); return view; }
@Override public void onPostExecute(View photo) { if (photo != null && !mFinished) { if (hasSelection() && getSelection() == mParent) { log("natural %s being rendered", (mSlot == NEXT ? "next" : "previous")); PhotoTable.this.addView( photo, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); PhotoTable.this.mOnDeck[mSlot] = photo; float width = (float) ((Integer) photo.getTag(R.id.photo_width)).intValue(); float height = (float) ((Integer) photo.getTag(R.id.photo_height)).intValue(); photo.setX(mSlot == PREV ? -2 * width : mWidth + 2 * width); photo.setY((mHeight - height) / 2); photo.addOnLayoutChangeListener( new OnLayoutChangeListener() { @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { PhotoTable.this.placeOnDeck(v, mSlot); v.removeOnLayoutChangeListener(this); } }); } else { recycle(photo); } } else { log("natural, %s was null!", (mSlot == NEXT ? "next" : "previous")); } }
public LcSearchView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.lc_search_view, this, true); mSearchTrack = findViewById(R.id.lc_search_plate); mTitleIcon = (ImageView) findViewById(R.id.lc_search_icon); mEditorTextView = (SearchAutoComplete) findViewById(R.id.lc_search_src_text); mClearBtn = (ImageView) findViewById(R.id.lc_search_clear_btn); mCancelTextView = (TextView) findViewById(R.id.lc_search_text_cancel); mTitleIcon.setOnClickListener(mOnClickListener); mClearBtn.setOnClickListener(mOnClickListener); mCancelTextView.setOnClickListener(mOnClickListener); mEditorTextView.setOnClickListener(mOnClickListener); mEditorTextView.setOnEditorActionListener(mOnEditorActionListener); mEditorTextView.setOnItemClickListener(mOnItemClickListener); mEditorTextView.addTextChangedListener(mTextWatcher); mEditorTextView.setSearchView(this); mEditorTextView.ensureImeVisible(true); // Inform any listener of focus changes mEditorTextView.setOnFocusChangeListener( new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { mTitleIcon.setAlpha(unfocusAlpha); mEditorTextView.setAlpha(unfocusAlpha); } else { mTitleIcon.setAlpha(1.0f); mEditorTextView.setAlpha(1.0f); } if (mOnTextFocusChangeListener != null) { mOnTextFocusChangeListener.onFocusChange(LcSearchView.this, hasFocus); } } }); mDropDownAnchor = findViewById(mEditorTextView.getDropDownAnchor()); if (mDropDownAnchor != null) { mDropDownAnchor.addOnLayoutChangeListener( new OnLayoutChangeListener() { @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { adjustDropDownSizeAndPosition(); } }); } int maxWidth = -1; CharSequence cancelText = null; CharSequence queryHintText = null; int clearBtnResId = R.drawable.lc_icon_search_view_clear_light; int titleIconId = R.drawable.lc_icon_search_view_search_light; int searchBgId = R.drawable.lc_selector_search_view_frame_light; int imeOptions = -1; int inputType = -1; boolean focusable = true; final Resources res = getResources(); TypedValue out = new TypedValue(); res.getValue(R.dimen.lc_search_view_default_text_alpha, out, true); unfocusAlpha = out.getFloat(); int queryTextSize = res.getDimensionPixelSize(R.dimen.lc_default_search_query_text_size); ColorStateList queryTextColor = res.getColorStateList(R.color.lc_search_view_query_text_color_light); ColorStateList queryHintTextColor = res.getColorStateList(R.color.lc_search_view_query_hint_text_color_light); int cancelTextSize = res.getDimensionPixelSize(R.dimen.lc_default_search_query_text_size); ColorStateList cancelTextColor = null; int mTrackMarginLeft = res.getDimensionPixelSize(R.dimen.lc_search_track_margin_left); mTrackMarginRight = res.getDimensionPixelSize(R.dimen.lc_search_track_margin_right); int mTrackMarginTop = res.getDimensionPixelSize(R.dimen.lc_search_track_margin_top); int mTrackMarginBottom = res.getDimensionPixelSize(R.dimen.lc_search_track_margin_bottom); int mTrackPaddingLeft = res.getDimensionPixelSize(R.dimen.lc_search_track_padding_left); int mTrackPaddingRight = res.getDimensionPixelSize(R.dimen.lc_search_track_padding_right); mMatchColor = res.getColor(R.color.lc_search_view_drop_down_match_text_color_light); mCursorResId = R.drawable.lc_shape_search_view_cursor_light; mDropDownBg = res.getDrawable(R.drawable.lc_search_drop_down_bg); mDropDownBlurRadius = 10; mPopupItemLayoutResId = R.layout.lc_search_dropdown_item_icons_2line_light; mAlwaysShowCancel = true; Drawable popupDivider = res.getDrawable(R.drawable.lc_search_drop_down_divider); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LcSearchView, defStyleAttr, defStyleRes); a.getValue(R.styleable.LcSearchView_lcSearchUnfocusAlpha, out); unfocusAlpha = out.getFloat(); queryTextSize = a.getDimensionPixelSize(R.styleable.LcSearchView_lcQueryTextSize, queryTextSize); cancelTextSize = a.getDimensionPixelSize(R.styleable.LcSearchView_lcCancelTextSize, cancelTextSize); if (a.hasValue(R.styleable.LcSearchView_lcQueryTextColor)) { queryTextColor = a.getColorStateList(R.styleable.LcSearchView_lcQueryTextColor); } if (a.hasValue(R.styleable.LcSearchView_lcQueryHintColor)) { queryHintTextColor = a.getColorStateList(R.styleable.LcSearchView_lcQueryHintColor); } if (a.hasValue(R.styleable.LcSearchView_lcCancelTextColor)) { cancelTextColor = a.getColorStateList(R.styleable.LcSearchView_lcCancelTextColor); } else { cancelTextColor = queryTextColor; } mTrackMarginBottom = a.getDimensionPixelSize(R.styleable.LcSearchView_lcInputMarginBottom, mTrackMarginBottom); mTrackMarginLeft = a.getDimensionPixelSize(R.styleable.LcSearchView_lcInputMarginLeft, mTrackMarginLeft); mTrackMarginRight = a.getDimensionPixelSize(R.styleable.LcSearchView_lcInputMarginRight, mTrackMarginRight); mTrackMarginTop = a.getDimensionPixelSize(R.styleable.LcSearchView_lcInputMarginTop, mTrackMarginTop); maxWidth = a.getDimensionPixelSize(R.styleable.LcSearchView_android_maxWidth, maxWidth); queryHintText = a.getText(R.styleable.LcSearchView_lcQueryHint); clearBtnResId = a.getResourceId(R.styleable.LcSearchView_lcClearIcon, clearBtnResId); titleIconId = a.getResourceId(R.styleable.LcSearchView_lcSearchIcon, titleIconId); searchBgId = a.getResourceId(R.styleable.LcSearchView_lcBackground, searchBgId); imeOptions = a.getInt(R.styleable.LcSearchView_android_imeOptions, imeOptions); inputType = a.getInt(R.styleable.LcSearchView_android_inputType, inputType); focusable = a.getBoolean(R.styleable.LcSearchView_android_focusable, focusable); mMatchColor = a.getColor(R.styleable.LcSearchView_lcMatchColor, mMatchColor); mCursorResId = a.getResourceId(R.styleable.LcSearchView_android_textCursorDrawable, mCursorResId); if (a.hasValue(R.styleable.LcSearchView_lcCancelText)) { cancelText = a.getString(R.styleable.LcSearchView_lcCancelText); } if (a.hasValue(R.styleable.LcSearchView_lcPopupBackground)) { mDropDownBg = a.getDrawable(R.styleable.LcSearchView_lcPopupBackground); } if (a.hasValue(R.styleable.LcSearchView_lcPopupListDivider)) { popupDivider = a.getDrawable(R.styleable.LcSearchView_lcPopupListDivider); } mDropDownBlurRadius = a.getDimensionPixelSize(R.styleable.LcSearchView_lcPopupBlurRadius, mDropDownBlurRadius); mPopupItemLayoutResId = a.getResourceId(R.styleable.LcSearchView_lcPopupItemLayout, mPopupItemLayoutResId); final int completeThreshold = a.getInt(R.styleable.LcSearchView_android_completionThreshold, 2); mAlwaysShowCancel = a.getBoolean(R.styleable.LcSearchView_lcAlwaysShowCancel, mAlwaysShowCancel); a.recycle(); mEditorTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, queryTextSize); mEditorTextView.setTextColor(queryTextColor); mEditorTextView.setHintTextColor(queryHintTextColor); HIDDEN_METHOD.setCursorDrawableRes(mEditorTextView, mCursorResId); mEditorTextView.setPopupBackground(mDropDownBg); mEditorTextView.setPopupListDivider(popupDivider); mEditorTextView.setPopupBlurRadius(mDropDownBlurRadius); mEditorTextView.setThreshold(completeThreshold); if (mEditorTextView.hasFocus()) { mTitleIcon.setAlpha(1.0f); mEditorTextView.setAlpha(1.0f); } else { mTitleIcon.setAlpha(unfocusAlpha); mEditorTextView.setAlpha(unfocusAlpha); } mCancelTextView.setTextColor(cancelTextColor); mCancelTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, cancelTextSize); if (mAlwaysShowCancel) { mCancelTextView.setVisibility(View.VISIBLE); } mClearBtn.setImageResource(clearBtnResId); mTitleIcon.setImageResource(titleIconId); mSearchTrack.setBackgroundResource(searchBgId); LinearLayout.LayoutParams plateParams = (LinearLayout.LayoutParams) mSearchTrack.getLayoutParams(); plateParams.topMargin = mTrackMarginTop; plateParams.bottomMargin = mTrackMarginBottom; plateParams.leftMargin = mTrackMarginLeft; plateParams.rightMargin = mAlwaysShowCancel ? 0 : mTrackMarginRight; LinearLayout.LayoutParams params = (LayoutParams) mTitleIcon.getLayoutParams(); params.leftMargin = mTrackPaddingLeft; params = (LayoutParams) mClearBtn.getLayoutParams(); params.rightMargin = mTrackPaddingRight; mCancelTextView.setPadding(mTrackMarginRight, 0, mTrackMarginRight, 0); if (maxWidth != -1) { setMaxWidth(maxWidth); } if (!TextUtils.isEmpty(queryHintText)) { setQueryHint(queryHintText); } if (imeOptions != -1) { setImeOptions(imeOptions); } if (inputType != -1) { setInputType(inputType); } if (cancelText != null) { mCancelTextView.setText(cancelText); } setFocusable(focusable); updateQueryHint(); }
/** * Present a sheet view to the user. If another sheet is currently presented, it will be * dismissed, and the new sheet will be shown after that * * @param sheetView The sheet to be presented. * @param viewTransformer The view transformer to use when presenting the sheet. */ public void showWithSheetView(final View sheetView, final ViewTransformer viewTransformer) { if (state != State.HIDDEN) { Runnable runAfterDismissThis = new Runnable() { @Override public void run() { showWithSheetView(sheetView, viewTransformer); } }; dismissSheet(runAfterDismissThis); return; } setState(State.PREPARING); LayoutParams params = (LayoutParams) sheetView.getLayoutParams(); if (params == null) { params = new LayoutParams( isTablet ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL); } if (isTablet && params.width == FrameLayout.LayoutParams.WRAP_CONTENT) { // Center by default if they didn't specify anything if (params.gravity == -1) { params.gravity = Gravity.CENTER_HORIZONTAL; } params.width = defaultSheetWidth; // Update start and end coordinates for touch reference int horizontalSpacing = screenWidth - defaultSheetWidth; sheetStartX = horizontalSpacing / 2; sheetEndX = screenWidth - sheetStartX; } super.addView(sheetView, -1, params); initializeSheetValues(); this.viewTransformer = viewTransformer; // Don't start animating until the sheet has been drawn once. This ensures that we don't do // layout while animating and that // the drawing cache for the view has been warmed up. tl;dr it reduces lag. getViewTreeObserver() .addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(this); post( new Runnable() { @Override public void run() { // Make sure sheet view is still here when first draw happens. // In the case of a large lag it could be that the view is dismissed before // it is drawn resulting in sheet view being null here. if (getSheetView() != null) { peekSheet(); } } }); return true; } }); // sheetView should always be anchored to the bottom of the screen currentSheetViewHeight = sheetView.getMeasuredHeight(); sheetViewOnLayoutChangeListener = new OnLayoutChangeListener() { @Override public void onLayoutChange( View sheetView, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { int newSheetViewHeight = sheetView.getMeasuredHeight(); if (state != State.HIDDEN && newSheetViewHeight < currentSheetViewHeight) { // The sheet can no longer be in the expanded state if it has shrunk if (state == State.EXPANDED) { setState(State.PEEKED); } setSheetTranslation(newSheetViewHeight); } currentSheetViewHeight = newSheetViewHeight; } }; sheetView.addOnLayoutChangeListener(sheetViewOnLayoutChangeListener); }