想了解android用PopWindow做下拉框实例代码的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于android下拉框实现的相关问题,此外,我们还将为您介绍关于AndroidPopup
想了解android用PopWindow做下拉框实例代码的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于android下拉框实现的相关问题,此外,我们还将为您介绍关于Android PopupWindow、android popupwindow 大小问题、Android Popupwindow 拖动、Android PopupWindow 的使用的新知识。
本文目录一览:- android用PopWindow做下拉框实例代码(android下拉框实现)
- Android PopupWindow
- android popupwindow 大小问题
- Android Popupwindow 拖动
- Android PopupWindow 的使用
android用PopWindow做下拉框实例代码(android下拉框实现)
最近在做下拉框,本来想用spinner,可是spinner达不到项目要求,跟同学同事问了一圈,都在用popwindow,网上看了一下,popwindow挺简单的,可定制性挺强的,符合我的要求,所以,借鉴网上看的代码,自己撸了一遍。写篇博客以防忘记。
首先,先写个自定义布局,代码如下
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="110dp" android:layout_height="wrap_content"> <LinearLayout android:layout_width="100dp" android:layout_height="wrap_content" android:background="@drawable/bg_circle_drop_down_qr_code" android:orientation="vertical" android:layout_marginRight="@dimen/padding_10" android:paddingBottom="0dp" android:paddingLeft="@dimen/padding_5" android:paddingRight="@dimen/padding_5" android:paddingTop="@dimen/padding_5"> <LinearLayout android:id="@+id/lin_scan_qr_code" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" android:paddingBottom="@dimen/padding_5" android:paddingTop="@dimen/padding_5"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_circle_scan_qr_code" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/padding_10" android:gravity="center" android:text="扫一扫" android:textColor="@color/color_white" android:textSize="@dimen/text_16" /> </LinearLayout> <View android:layout_width="wrap_content" android:layout_height="1px" android:layout_marginLeft="@dimen/padding_3" android:layout_marginRight="@dimen/padding_3" android:background="@color/color_white" /> <LinearLayout android:id="@+id/lin_my_qr_code" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" android:paddingBottom="@dimen/padding_5" android:paddingTop="@dimen/padding_5"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_circle_my_qr_code" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/padding_10" android:gravity="center" android:text="二维码" android:textColor="@color/color_white" android:textSize="@dimen/text_16" /> </LinearLayout> </LinearLayout> </LinearLayout>
第二步,在代码中定义popwindow样式,绑定点击事件,代码如下:
// // 获取自定义布局文件pop.xml的视图 View customView = getActivity().getLayoutInflater().inflate(R.layout.lay_circle_pop_drop_down_qr_code,null,false); // 创建PopupWindow实例,200,150分别是宽度和高度 mQrCodePopWindow = new PopupWindow(customView,CommonUtil.dipToPx(getContext(),110),ViewGroup.LayoutParams.WRAP_CONTENT,true); // 设置动画效果 [R.style.AnimationFade 是自己事先定义好的] // popupwindow.setAnimationStyle(R.style.AnimationFade); // popupwindow.setTouchable(true); // popupwindow.setoutsidetouchable(true); mQrCodePopWindow.setBackgroundDrawable(new BitmapDrawable()); customView.findViewById(R.id.lin_scan_qr_code).setonClickListener(v -> { ToastUtil.show(getContext(),"扫一扫"); dismissQrCodePopWindow(); }); customView.findViewById(R.id.lin_my_qr_code).setonClickListener(v -> ToastUtil.show(getContext(),"二维码"));
注意,代码中的true为setFoucusable,如要点击空白处隐藏popwindow的话,setFocusable(true)和setBackground()两者必不可少(亲测)。
最后,为空间添加点击事件,控制下拉框的显示隐藏,代码如下:
@OnClick(R.id.lin_top_right) public void onClick(View v) { if (mQrCodePopWindow != null&& mQrCodePopWindow.isShowing()) { mQrCodePopWindow.dismiss(); } else { initQrCodePopWindow(); mQrCodePopWindow.showAsDropDown(v); } }
(由于暂时没有发现好的动画效果,所以没有添加动画,如果大家有发现好的动画,还请告知一二,在此谢过)
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
Android PopupWindow
Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:
- AlertDialog的位置固定,而PopupWindow的位置可以随意
- AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的
PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
- showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
- showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
- showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
下面通过一个Demo讲解(解释看注释):
main.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:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/button01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="以自己为Anchor,不偏移" />
<Button
android:id="@+id/button02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="以自己为Anchor,有偏移" />
<Button
android:id="@+id/button03"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="以屏幕中心为参照,不偏移(正中间)" />
<Button
android:id="@+id/button04"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="以屏幕下方为参照,下方中间" />
</LinearLayout>
popup_window.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FF00"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择状态:"
android:textColor="@android :color/white"
android:textSize="20px" />
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RadioButton android:text="在线" />
<RadioButton android:text="离线" />
<RadioButton android:text="隐身" />
</RadioGroup>
</LinearLayout>
PopupWindowDemoActivity.java
package com.tianjf;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
public class PopupWindowDemoActivity extends Activity implements OnClickListener,
OnCheckedChangeListener {
private Button mbutton01;
private Button mbutton02;
private Button mbutton03;
private Button mbutton04;
private PopupWindow mPopupWindow;
// 屏幕的width
private int mScreenWidth;
// 屏幕的height
private int mScreenHeight;
// PopupWindow的width
private int mPopupWindowWidth;
// PopupWindow的height
private int mPopupWindowHeight;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mbutton01 = (Button) findViewById(R.id.button01);
mbutton02 = (Button) findViewById(R.id.button02);
mbutton03 = (Button) findViewById(R.id.button03);
mbutton04 = (Button) findViewById(R.id.button04);
mbutton01.setOnClickListener(this);
mbutton02.setOnClickListener(this);
mbutton03.setOnClickListener(this);
mbutton04.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
// 相对某个控件的位置(正左下方),无偏移
case R.id.button01:
getPopupWindowInstance();
mPopupWindow.showAsDropDown(v);
break;
// 相对某个控件的位置(正左下方),有偏移
case R.id.button02:
getPopupWindowInstance();
mPopupWindow.showAsDropDown(v, 50, 50);// X、Y方向各偏移50
break;
// 相对于父控件的位置,无偏移
case R.id.button03:
getPopupWindowInstance();
mPopupWindow.showAtLocation(v, Gravity.CENTER, 0, 0);
break;
// 相对于父控件的位置,有偏移
case R.id.button04:
getPopupWindowInstance();
mPopupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 50);
break;
default:
break;
}
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
mPopupWindow.dismiss();
}
/*
* 获取PopupWindow实例
*/
private void getPopupWindowInstance() {
if (null != mPopupWindow) {
mPopupWindow.dismiss();
return;
} else {
initPopuptWindow();
}
}
/*
* 创建PopupWindow
*/
private void initPopuptWindow() {
LayoutInflater layoutInflater = LayoutInflater.from(this);
View popupWindow = layoutInflater.inflate(R.layout.popup_window, null);
RadioGroup radioGroup = (RadioGroup) popupWindow.findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(this);
// 创建一个PopupWindow
// 参数1:contentView 指定PopupWindow的内容
// 参数2:width 指定PopupWindow的width
// 参数3:height 指定PopupWindow的height
mPopupWindow = new PopupWindow(popupWindow, 100, 130);
// 获取屏幕和PopupWindow的width和height
mScreenWidth = getWindowManager().getDefaultDisplay().getWidth();
mScreenWidth = getWindowManager().getDefaultDisplay().getHeight();
mPopupWindowWidth = mPopupWindow.getWidth();
mPopupWindowHeight = mPopupWindow.getHeight();
}
}
android popupwindow 大小问题
由于popupWindow 的视图是从xml 中渲染的,关于popupwindow的大小碰到了一个问题:跟想象中的大小不一样。于是网上查了一点资料,没找到啥干货,不过在这篇文章中讲了一点。
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0702/1627.html
new PopupWindow(pop_view, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
这里的WRAP_CONTENT可以换成fill_parent 也可以是具体的数值,它是指PopupWindow的大小,也就是contentview的大小,注意popupwindow根据这个大小显示你的View,如果你的View本身是从xml得到的,那么xml的第一层view的大小属性将被忽略。相当于popupWindow的width和height属性直接和第一层View相对应。
popupWindow 设置为WRAP_CONTENT ,我想得到的是一个宽150dip 高80dip的popupwindow,需要额外加一层。LinearLayout ,这个LinearLayout 的layout_width和layout_height为任意值。而我们真正想显示的View 放在第二层,并且 android:layout_width="150.0dip" android:layout_height="80.0dip"
这样就可以解决大小问题。
但是我们的pop还需要控制显示位置,要控制这个pop 相对于某个view 来显示,可以使用以下方式。
int[] location = new int[2];
v.getLocationOnScreen(location);//获得view 的位置
pw.getContentView().measure(0,0);
int width = pw.getContentView().getMeasuredWidth();
int height = pw.getContentView().getMeasuredHeight();//这三行代码在pop 显示之前获得它的大小,由于pop 是设置的wrap_content
pw.showAtLocation(v, Gravity.NO_GRAVITY,location[0]-width,location[1]-(height-v.getHeight())/2);//显示在view 的左中位置。
后记:项目算是告一段落了,也学到了不少东西。
Android Popupwindow 拖动
关于View的拖动你们应该比较了解了,好比对一个控件IamgeView拖动,或者一个视图View拖动,实现方式也很容易,继承OnTouchListener接口,而后重写onTouch方法,在触屏事件进行处理便可。可是Popupwindow如何实现拖动呢,咱们都知道它和普通的View不同,由于它不是继承于View类的,可是它的实现倒是和View密切相关的,由于咱们都知道Android视图的显示都是由View来处理的,因此必定离不开它。从Popupwindow的实现就能够看出来,ide
import com.android.internal.R; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.StateListDrawable; import android.os.Build; import android.os.IBinder; import android.util.AttributeSet; import android.view.Gravity; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowManager; import java.lang.ref.WeakReference;上面是它的导包状况,基本上不是和View相关,就是和绘图相关。所以关于Popupwindow的拖动这一块,也和View有联系。首先看一下它的API,看一看有没有和View移动、变化相关的方法,果真在最后有几个update()方法,以下:
update()方法用来更新Popupwindow的位置和大小的,那么问题就好解决了。看代码:布局
package com.example.drag_and_drop_movablepopupwindow; import android.support.v7.app.ActionBaractivity; import android.graphics.Color; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.PopupWindow; import android.widget.TextView; public class MainActivity extends ActionBaractivity { private Button btnopenPopup; private int mCurrentX; private int mCurrentY; private PopupWindow mPopup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnopenPopup = (Button) findViewById(R.id.openpopup); btnopenPopup.setonClickListener(new Button.OnClickListener() { @Override public void onClick(View arg0) { creatPopubWindow_1(); } }); } /** * 1 */ private void creatPopubWindow_1() { LayoutInflater layoutInflater = (LayoutInflater) getBaseContext() .getSystemService(LAYOUT_INFLATER_SERVICE); View popupView = layoutInflater.inflate(R.layout.popup, null); final PopupWindow popupWindow = new PopupWindow(popupView, 200, 200); Button btndismiss = (Button) popupView.findViewById(R.id.dismiss); btndismiss.setonClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { popupWindow.dismiss(); } }); popupWindow.showAsDropDown(btnopenPopup, 50, 50); popupView.setonTouchListener(new OnTouchListener() { int orgX, orgY; int offsetX, offsetY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: orgX = (int) event.getX(); orgY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: offsetX = (int) event.getRawX() - orgX; offsetY = (int) event.getRawY() - orgY; popupWindow.update(offsetX, offsetY, -1, -1, true); break; } return true; } }); } }
效果如图:ui
首先对Popupwindow设置触摸事件,而后在回调方法中进行计算,若是手指拖动了Popupwindow,那么就调用update()方法来更新它的位置。有些同窗可能不太理解参数-1是什么意思,在上面的API中,写明的是宽和高,这里怎么变成-1了呢,看一下Popupwindow源代码就明白了。this
/** * <p>Updates the position and the dimension of the popup window. Width and * height can be set to -1 to update location only. Calling this function * also updates the window with the current popup state as * described for {@link #update()}.</p> * * @param x the new x location * @param y the new y location * @param width the new width, can be -1 to ignore * @param height the new height, can be -1 to ignore * @param force reposition the window even if the specified position * already seems to correspond to the LayoutParams */ public void update(int x, int y, int width, int height, boolean force) { if (width != -1) { mLastWidth = width; setWidth(width); } if (height != -1) { mLastHeight = height; setHeight(height); } if (!isShowing() || mContentView == null) { return; } WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams(); boolean update = force; final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; if (width != -1 && p.width != finalWidth) { p.width = mLastWidth = finalWidth; update = true; } final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; if (height != -1 && p.height != finalHeight) { p.height = mLastHeight = finalHeight; update = true; } if (p.x != x) { p.x = x; update = true; } if (p.y != y) { p.y = y; update = true; } final int newAnim = computeAnimationResource(); if (newAnim != p.windowAnimations) { p.windowAnimations = newAnim; update = true; } final int newFlags = computeFlags(p.flags); if (newFlags != p.flags) { p.flags = newFlags; update = true; } if (update) { setLayoutDirectionFromAnchor(); mWindowManager.updateViewLayout(mPopupView, p); } }前两个if判断已经说得很清楚了,若是参数是-1的话,就不改变Popupwindow的大小了,由于咱们只是移动位置,因此才这样写。那关于Popupwindow的移动最后是怎么实现的呢,能够看出就是调用WindowManager的updateViewLayout()方法,这个方法在WindowManager中并无实现,它是ViewManager接口里面的方法,WindowManager继承了ViewManager。说到ViewManager,它里面定义的方法都很经常使用,看代码:
/** Interface to let you add and remove child views to an Activity. To get an instance * of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. */ public interface ViewManager { /** * Assign the passed LayoutParams to the passed View and add the view to the window. * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming * errors, such as adding a second view to a window without removing the first view. * <p>Throws {@link android.view.WindowManager.InvaliddisplayException} if the window is on a * secondary {@link display} and the specified display can't be found * (see {@link android.app.Presentation}). * @param view The view to be added to this window. * @param params The LayoutParams to assign to view. */ public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); }这下你们应该明了,咱们常常用的addView、removeView方法就是在这里面定义的,那么谁去实现呢?就是Layout控件,好比LinearLayout、RelativeLayout等,因此咱们刚才用的updateViewLayout()方法也是在xml布局文件中的layout定义好的。
Android PopupWindow 的使用
在我理解其实PopupWindow其实类似于一个不能动的Widget(仅从显示效果来说!)。它是浮在别的窗口之上的.
下面我将给大家做一个简单的Demo,类似于音乐播放器的Widget的效果,点击Button的时候出来PopupWindow,首先我们看一下效果图:
下面是核心代码:
?
package
com.android.tutor;
import
android.app.Activity;
import
android.content.Context;
import
android.os.Bundle;
import
android.view.Gravity;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.view.ViewGroup.LayoutParams;
import
android.widget.Button;
import
android.widget.PopupWindow;
public
class
PopupWindowDemo
extends
Activity
implements
OnClickListener{
private
Button btn;
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(
this
);
}
@Override
public
void
onClick(View v) {
Context mContext = PopupWindowDemo.
this
;
if
(v.getId() == R.id.btn) {
LayoutInflater mLayoutInflater = (LayoutInflater) mContext
.getSystemService(LAYOUT_INFLATER_SERVICE);
View music_popunwindwow = mLayoutInflater.inflate(
R.layout.music_popwindow,
null
);
PopupWindow mPopupWindow =
new
PopupWindow(music_popunwindwow, LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
mPopupWindow.showAtLocation(findViewById(R.id.main), Gravity.RIGHT|Gravity.BOTTOM,
0
,
0
);
}
}
}
需要强调的是这里PopupWindow必须有某个事件触发才会显示出来,不然总会抱错,不信大家可以试试!
随着这个问题的出现,就会同学问了,那么我想初始化让PopupWindow显示出来,那怎么办了,不去寄托于其他点击事件。在这里我用了定时器Timer来实现这样的效果,当然这里就要用到Handler了:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package
com.android.tutor;
import
java.util.Timer;
import
java.util.TimerTask;
import
android.app.Activity;
import
android.content.Context;
import
android.os.Bundle;
import
android.os.Handler;
import
android.os.Message;
import
android.view.Gravity;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup.LayoutParams;
import
android.widget.PopupWindow;
public
class
PopupWindowDemo
extends
Activity{
private
Handler mHandler =
new
Handler(){
public
void
handleMessage(Message msg) {
switch
(msg.what) {
case
1
:
showPopupWindow();
break
;
}
};
};
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create the timer
Timer timer =
new
Timer();
timer.schedule(
new
initPopupWindow(),
100
);
}
private
class
initPopupWindow
extends
TimerTask{
@Override
public
void
run() {
Message message =
new
Message();
message.what =
1
;
mHandler.sendMessage(message);
}
}
public
void
showPopupWindow() {
Context mContext = PopupWindowDemo.
this
;
LayoutInflater mLayoutInflater = (LayoutInflater) mContext
.getSystemService(LAYOUT_INFLATER_SERVICE);
View music_popunwindwow = mLayoutInflater.inflate(
R.layout.music_popwindow,
null
);
PopupWindow mPopupWindow =
new
PopupWindow(music_popunwindwow,
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
mPopupWindow.showAtLocation(findViewById(R.id.main), Gravity.CENTER,
0
,
0
);
}
}
|
效果如下图:
关于android用PopWindow做下拉框实例代码和android下拉框实现的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android PopupWindow、android popupwindow 大小问题、Android Popupwindow 拖动、Android PopupWindow 的使用等相关知识的信息别忘了在本站进行查找喔。
本文标签: