Android Filter menu effect

preface

Because the popupwindow of Android m is inconsistent with the previous version, the author can't find a way to monitor the physical return key by code, so find another way to implement the filter menu. Version 5.0 and earlier can be implemented with popupwindow. Please refer to popupwindow usage for details.

This article is implemented by dialog.

Implementation steps

1. Set theme

The general settings are as follows

<style name="Translucent_NoTitle" parent="android:style/Theme.Dialog">
  <item name="android:windowNoTitle">true</item>
  <item name="android:background">#00000000</item>
  <item name="android:windowBackground">@android:color/transparent</item>
  <item name="android:windowAnimationStyle">@null</item>
  <item name="android:windowIsFloating">true</item>
  <item name="android:colorBackgroundCacheHint">@null</item>
  <item name="android:windowIsTranslucent">true</item>
  <item name="android:backgroundDimEnabled">false</item><span style="white-space:pre"> </span>背景暗淡效果
</style>

You can also use android.r.style.theme_ Panel and android.r.style.theme_ Light_ Panel。 android.R.style.Theme_ The panel code is as follows, which is the same as above.

<style name="Theme.Panel">
  <item name="windowBackground">@color/transparent</item>
  <item name="colorBackgroundCacheHint">@null</item>
  <item name="windowFrame">@null</item>
  <item name="windowContentOverlay">@null</item>
  <item name="windowAnimationStyle">@null</item>
  <item name="windowIsFloating">true</item>
  <item name="backgroundDimEnabled">false</item>
  <item name="windowIsTranslucent">true</item>
  <item name="windowNoTitle">true</item>
</style>

2. Sets the width and height of the content

We implement it through windowmanager.layoutparams.

WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
  layoutParams.width = screenWidth;
  layoutParams.height = contentHeight;
  layoutParams.gravity = Gravity.TOP;
  layoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; //不阻塞事件传递到后面的窗口
  getWindow().setAttributes(layoutParams);

Here, set layoutparams.flags | = windowmanager.layoutparams.flag_ NOT_ TOUCH_ MODAL; Then the buttons in the rear window can respond to touch events (for example, horizon Scrollview can scroll horizontally).

3. Animate

Implemented by valueanimator.

enter = ValueAnimator.ofFloat(0,1f).setDuration(350);
  enter.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    dialogContent.setTranslationY((1 - animation.getAnimatedFraction()) * -contentHeight);
   }
  });

  out = ValueAnimator.ofFloat(0,1f).setDuration(350);
  out.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    dialogContent.setTranslationY(animation.getAnimatedFraction() * -contentHeight);
   }
  });
  out.addListener(new Animator.AnimatorListener() {
   @Override
   public void onAnimationStart(Animator animation) {

   }

   @Override
   public void onAnimationEnd(Animator animation) {
    dismiss();
   }

   @Override
   public void onAnimationCancel(Animator animation) {

   }

   @Override
   public void onAnimationRepeat(Animator animation) {

   }
  });

A series of settings are made for enter and out above to start and end the monitoring of out animation. The start () method of enter is called in onStart ().

@Override
 protected void onStart() {
  super.onStart();
  dialogContent.post(new Runnable() {
   @Override
   public void run() {
    enter.start();
   }
  });
 }

Through the post mode of view, enter. Start () will be executed after the view hierarchy (view tree) is built (that is, after the view is built). View.post source code:

public boolean post(Runnable action) {
  final AttachInfo attachInfo = mAttachInfo;
  if (attachInfo != null) {
   return attachInfo.mHandler.post(action);
  }
  // Assume that post will succeed later
  ViewRootImpl.getRunQueue().post(action);
  return true;
 }

The seventh line is the key code. Viewrootimpl is the top of the view level, which implements the necessary protocols between view and WindowManager. Runqueue: the run queue is used to queue up future work of views without Handler Association. Therefore, the enter. Start () method will be called when the dialog view is displayed

Listening return key:

@Override
 public boolean onKeyDown(int keyCode,KeyEvent event) {
  if (keyCode == KeyEvent.KEYCODE_BACK) {
   out.start();
   return true;
  }
  return super.onKeyDown(keyCode,event);
 }

After the out animation is executed, the dismiss () method is called in onAnimationEnd.

4. Displayed under the clicked view

public void showAsDropView(View view) {
  WindowManager.LayoutParams lp = getWindow().getAttributes();
  lp.width = screenWidth;
  int[] location = new int[2];
  view.getLocationOnScreen(location);
//  view.getLocationInWindow(location);<span style="white-space:pre"> </span>这里跟上面一句的效果一样,不知有什么区别
  lp.y = location[1]-PhoneConstant.statusHeight+view.getHeight();
  lp.gravity = Gravity.TOP;
  getWindow().setAttributes(lp);
  contentTop = location[1];
  show();
 }

Phoneconstant.statusheight is the height of the status bar, which is obtained by reflection

//反射获取状态栏高度
  Class<?> c = null;
  Object obj = null;
  Field field = null;
  int x = 0,sbar = 0;
  try {
   c = Class.forName("com.android.internal.R$dimen");
   obj = c.newInstance();
   field = c.getField("status_bar_height");
   x = Integer.parseInt(field.get(obj).toString());
   PhoneConstant.statusHeight = getResources().getDimensionPixelSize(x);
  } catch(Exception e1) {
   e1.printStackTrace();
  }

It can also be obtained in the following ways

Rect outRect = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect); 

However, it is invalid to put it directly in oncreate of activity. It can only be obtained after the interface is drawn, which can be obtained through view. Post().

design sketch:

In addition, for the custom dialog inherited from alertdialog, clicking edit text does not pop up the soft keyboard, so it is generally inherited from dialog.

Control dialog box input method pop-up, call

The code is as follows:

getWindow().setSoftInputMode(WindowManager.LayoutParams.soFT_INPUT_ADJUST_RESIZE|WindowManager.LayoutParams.soFT_INPUT_STATE_HIDDEN);

The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>