当前位置:网站首页>Popupwindow touch event transparent transmission scheme
Popupwindow touch event transparent transmission scheme
2022-06-24 20:25:00 【coder_ szc】
background
Sometimes we pop up a PopupWindow Pop up , There is such a need :
Click the control on the pop-up window ( Non blank area ) when , Execute the click logic of the control ;
When the finger touches the blank area on the pop-up window , The event was transmitted to the... Under the pop-up window view, That is, it does not affect the normal business logic
Ideas
to PopupWindow Set up onTouchInterceptor, Determine whether the coordinates of the touch event are in a component in the pop-up window , If yes, the touch event is transmitted by the pop-up root view ; Or give it to activity To deliver events .
Code implementation
Construction scenario :Activity There is one of them. ListView, There are two in the pop-up window Button, One is responsible for displaying Toast, One is responsible for controlling the other Button The visibility of .
Set up UI Layout
Here are the three corresponding layout files :
main interface activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/text_view"
android:visibility="gone"
/>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>ListView List item layout item_layout.xml:
<?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/text_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>Pop up window layout window_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/purple_500">
<Button
android:id="@+id/btn_window"
android:text="Button1 for test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_hide"
android:text="Hide Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text_window"
android:textIsSelectable="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/many_letters"/>
</LinearLayout>Set up the data
Mainly for ListView Set up the data , Our adapter class is shown below :
public class MyAdapter extends BaseAdapter {
private List<String> mList;
private Context mContext;
public MyAdapter(List<String> list, Context context) {
mList = list;
mContext = context;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public String getItem(int i) {
return mList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.item_layout, null);
}
TextView textItem = view.findViewById(R.id.text_item);
textItem.setText(getItem(i));
return view;
}
}And then, in MainActivity In the binding ListView And adapters :
public class MainActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.text_view);
ListView listView = findViewById(R.id.list);
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 200; i++) {
list.add("No." + i);
}
MyAdapter adapter = new MyAdapter(list, this);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
...
}
...
}3)、 Construct pop ups
Defining attributes mWindowView, The transparent transmission of later events will use . And then, in MainActivity Of onCreate() in , Load the popup view under the binding adapter , And set the properties :
public class MainActivity extends AppCompatActivity {
...
private View mWindowView;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mWindowView = LayoutInflater.from(this).inflate(R.layout.window_layout, null);
PopupWindow window = new PopupWindow(this);
mButton = windowView.findViewById(R.id.btn_window);
mButton.setOnClickListener(view -> {
Toast.makeText(MainActivity.this, "Button on window has been clicked!", Toast.LENGTH_SHORT).show();
});
mHide = windowView.findViewById(R.id.btn_hide);
mHide.setOnClickListener(v -> {
mButton.setVisibility(mButton.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
});
...
window.setContentView(mWindowView);
window.setWidth(750);
window.setHeight(1750);
// The display pop-up window must post
textView.post(() -> {
window.showAtLocation(textView, Gravity.START, 0, 0);
});
...
}
...
}Achieve transparent transmission of touch events
We need to set a touch interceptor for the pop-up window , First try to get the touched sub view , If there is , Indicates that no blank area has been touched , Pop up to deliver and consume events ; otherwise , Indicates that a blank area has been touched , First modify the event coordinates , Again to activity:
public class MainActivity extends AppCompatActivity {
private Button mButton;
private Button mHide;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
window.setTouchInterceptor((view, motionEvent) -> { // Set the touch interceptor
// Get the touched subview
View target = Utils.getViewTouchedByEvent(mWindowView, motionEvent);
// Pop up processing events
if (target != null) {
mWindowView.dispatchTouchEvent(motionEvent);
return true;
}
// No child view consumption Events , Just send the incident to activity;
// First, transform the event coordinates , Then hand it over to the main interface for transmission , Do not consume the event stream
int[] popupLocation = new int[2];
mWindowView.getLocationOnScreen(popupLocation);
event.offsetLocation(popupLocation[0], popupLocation[1]);
MainActivity.this.dispatchTouchEvent(motionEvent);
return false;
});
...
}
...
}The method for obtaining the touched sub view getViewTouchedByEvent() It's encapsulated in Utils Class :
public class Utils {
public static View getViewTouchedByEvent(View view, MotionEvent event) {
if (view == null || event == null) {
return null;
}
if (!(view instanceof ViewGroup)) {
return isDebugWindowValidTouched(view, event) ? view : null;
}
ViewGroup parent = ((ViewGroup) view);
int childrenCount = parent.getChildCount();
for (int i = 0; i < childrenCount; i++) {
View target = getViewTouchedByEvent(parent.getChildAt(i), event);
if (target != null) {
return target;
}
}
return null;
}
// Judge event Whether the coordinates are in the view view in
private static boolean isDebugWindowValidTouched(View view, MotionEvent event) {
if (event == null || view == null) {
return false;
}
if (view.getVisibility() != View.VISIBLE) {
return false;
}
final float eventRawX = event.getRawX();
final float eventRawY = event.getRawY();
RectF rect = new RectF();
int[] location = new int[2];
view.getLocationOnScreen(location);
float x = location[0];
float y = location[1];
rect.left = x;
rect.right = x + view.getWidth();
rect.top = y;
rect.bottom = y + view.getHeight();
return rect.contains(eventRawX, eventRawY) ;
}
}The main step of this method is to judge the current view Is it right? ViewGroup: If yes , according to event The coordinates and view Coordinate judgment of view Is it touched ; Otherwise, yes view All son view Recursively call getViewTouchedByEvent(), To get the lowest level touched by the touch event view.
Last , Say when you touch a blank area , Pass the touch event to activity front , Reason for modifying event coordinates : Event coordinates are the coordinates of the event in the view , And at the bottom activity Is a normal size , Therefore, you need to add the coordinate offset of the pop-up root view on the screen , Again to activity.
effect

边栏推荐
- RF_ DC system clock setting gen1/gen2
- Database index can improve query efficiency. Ask what will improve, what is the difference between inapplicable index and index use, and what will happen.
- 【云驻共创】ModelBox隔空作画 绘制你的专属画作
- R for Data Science (notes) -- data transformation (used by filter)
- Predicate
- 苹果、微软、谷歌不再掐架,今年要合力干一件大事
- 宅男救不了元宇宙
- Ribbon源码分析之@LoadBalanced与LoadBalancerClient
- 等等党们的胜利!挖矿退潮后,显卡价格全面暴跌
- The Network Security Review Office launched a network security review on HowNet, saying that it "has a large amount of important data and sensitive information"
猜你喜欢

Write a positive integer to the node and return a floating-point number multiplied by 0.85 when reading the node

Saltstack state state file configuration instance

The agile way? Is agile development really out of date?

顺序栈遍历二叉树

Two fellow countrymen from Hunan have jointly launched a 10 billion yuan IPO

The Network Security Review Office launched a network security review on HowNet, saying that it "has a large amount of important data and sensitive information"

Apple, Microsoft and Google will no longer fight each other. They will work together to do a big thing this year

物聯網?快來看 Arduino 上雲啦

Apache+PHP+MySQL环境搭建超详细!!!

Byte and Tencent have also come to an end. How fragrant is this business of "making 30million yuan a month"?
随机推荐
What are the functions of IBPs open source form designer?
How does the video platform import the old database into the new database?
Bytebase joins Alibaba cloud polardb open source database community
用自身细胞作为原料,首例3D打印耳朵移植成功!未来可打印更复杂器官
Maps are grouped according to the values of the passed in parameters (similar to database groupby)
"Ningwang" was sold and bought at the same time, and Hillhouse capital has cashed in billions by "selling high and absorbing low"
【CANN文档速递06期】初识TBE DSL算子开发
【Go語言刷題篇】Go從0到入門4:切片的高級用法、初級複習與Map入門學習
Making startup U disk -- Chinese cabbage U disk startup disk making tool V5.1
Compressed list of redis data structures
unity实战之lol技能释放范围
gateway
Stackoverflow 年度报告 2022:开发者最喜爱的数据库是什么?
Nodered has no return value after successfully inserting into the database (the request cannot be ended)
What is CNN (convolutional neural network)
Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!
Zadig + cave Iast: let safety dissolve in continuous delivery
消息称腾讯正式宣布成立“XR”部门,押注元宇宙;谷歌前 CEO:美国即将输掉芯片竞争,要让台积电、三星建更多工厂...
两位湖南老乡,联手干出一个百亿IPO
[suggested collection] time series prediction application and paper summary