編輯:關於android開發
我們打開QQ空間的時候有個箭頭按鈕點擊之後彈出PopupWindow會根據位置的變化顯示在箭頭的上方還是下方,比普通的PopupWindow彈在屏幕中間顯示好看的多。
先看QQ空間效果圖:
這個要實現這個效果可以分幾步進行
1.第一步自定義PopupWindow,實現如圖的樣式,這個繼承PopupWindow自定義布局很容易實現
2.得到點擊按鈕的位置,根據位置是否在屏幕的中間的上方還是下方,將PopupWindow顯示在控件的上方或者下方
3.適配問題,因為PopupWindow上面的操作列表是動態的所以要自定義listView
4.動畫效果+背景變暗
通過步驟分析,我們就很清晰的了解我們要做什麼,話不多說,從第一步開始吧
下面自定義PopupWindow實現效果
1.重寫listView,重新計算高度(一般也應用於解決ScrollView嵌套listView只顯示一行的問題)
public class MyListView extends ListView {
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST));
}
}
2.自定義PopupWindow的布局文件
<?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:gravity="right">
<ImageView
android:id="@+id/arrow_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="28dp"
android:src="@drawable/arrow_up_white"
android:visibility="visible"/>
<com.widget.MyListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/normal_margin8"
android:layout_marginTop="-1dp"
android:layout_marginBottom="-1dp"
android:dividerHeight="0dp"
android:layout_marginLeft="@dimen/normal_margin8"
android:layout_marginRight="@dimen/normal_margin8"
android:scrollbars="none"
android:background="@drawable/custom_white"
android:divider="@null"></com.widget.MyListView>
<ImageView
android:id="@+id/arrow_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="28dp"
android:src="@drawable/arrow_down_white"
android:visibility="visible"/>
</LinearLayout>
2.PopupWindow彈出動畫以及消失動畫
popshow_operation_anim_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="90%"
android:pivotY="0%"
android:fillAfter="false"
android:duration="300" >
</scale>
</set>
popshow_operation_anim_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="90%"
android:pivotY="100%"
android:fillAfter="false"
android:duration="250" >
</scale>
</set>
消失動畫是漸隱動畫可以自己定義,同理。
3.重寫PopupWindow了
public class CustomOperationPopWindow extends PopupWindow {
private Context context;
private View conentView;
private View backgroundView;
private Animation anim_backgroundView;
private MyListView listView;
private TypeSelectPopuAdapter selectAdapter;
ImageView arrow_up, arrow_down;
List<TypeSelect> typeSelectlist = new ArrayList<>();
int[] location = new int[2];
private OnItemListener onItemListener;
private AdapterView.OnItemClickListener onItemClickListener;
public interface OnItemListener {
public void OnItemListener(int position, TypeSelect typeSelect);
}
;
public void setOnItemMyListener(OnItemListener onItemListener) {
this.onItemListener = onItemListener;
}
public CustomOperationPopWindow(Context context) {
this.context = context;
initView();
}
public CustomOperationPopWindow(Context context, List<TypeSelect> typeSelectlist) {
this.context = context;
this.typeSelectlist = typeSelectlist;
initView();
}
private void initView() {
this.anim_backgroundView = AnimationUtils.loadAnimation(context, R.anim.alpha_show_anim);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.conentView = inflater.inflate(R.layout.view_operation_popupwindow, null);
// 設置SelectPicPopupWindow的View
this.setContentView(conentView);
// 設置SelectPicPopupWindow彈出窗體的寬
this.setWidth(LayoutParams.MATCH_PARENT);
// 設置SelectPicPopupWindow彈出窗體的高
this.setHeight(LayoutParams.WRAP_CONTENT);
// 設置SelectPicPopupWindow彈出窗體可點擊
this.setFocusable(true);
this.setOutsideTouchable(true);
// 刷新狀態
this.update();
// 實例化一個ColorDrawable顏色為半透明
ColorDrawable dw = new ColorDrawable(0000000000);
// 點back鍵和其他地方使其消失,設置了這個才能觸發OnDismisslistener ,設置其他控件變化等操作
this.setBackgroundDrawable(dw);
// 設置SelectPicPopupWindow彈出窗體動畫效果
this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);
this.listView = (MyListView) conentView.findViewById(R.id.lv_list);
this.arrow_up = (ImageView) conentView.findViewById(R.id.arrow_up);
this.arrow_down = (ImageView) conentView.findViewById(R.id.arrow_down);
//設置適配器
this.selectAdapter = new TypeSelectPopuAdapter(context, typeSelectlist,
R.layout.item_operation_popu);
this.listView.setAdapter(selectAdapter);
this.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (isShowing()) {
dismiss();
}
onItemListener.OnItemListener(position, typeSelectlist.get(position));
}
});
this.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
if (backgroundView != null) {
backgroundView.setVisibility(View.GONE);
}
}
});
}
//設置數據
public void setDataSource(List<TypeSelect> typeSelectlist) {
this.typeSelectlist = typeSelectlist;
this.selectAdapter.notifyDataSetChanged();
}
/**
* 沒有半透明背景 顯示popupWindow
*
* @param
*/
public void showPopupWindow(View v) {
v.getLocationOnScreen(location); //獲取控件的位置坐標
//獲取自身的長寬高
conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
if (location[1] > MainApplication.SCREEN_H / 2 + 100) { //MainApplication.SCREEN_H 為屏幕的高度,方法可以自己寫
this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);
arrow_up.setVisibility(View.GONE);
arrow_down.setVisibility(View.VISIBLE);
this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight());
} else {
this.setAnimationStyle(R.style.operation_popwindow_anim_style_down);
arrow_up.setVisibility(View.VISIBLE);
arrow_down.setVisibility(View.GONE);
this.showAsDropDown(v, 0, 0);
}
}
/**
* 攜帶半透明背景 顯示popupWindow
*
* @param
*/
public void showPopupWindow(View v, View backgroundView) {
this.backgroundView = backgroundView;
v.getLocationOnScreen(location); //獲取控件的位置坐標
//獲取自身的長寬高
conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
backgroundView.setVisibility(View.VISIBLE);
//對view執行動畫
backgroundView.startAnimation(anim_backgroundView);
if (location[1] > MainApplication.SCREEN_H / 2 + 100) { //若是控件的y軸位置大於屏幕高度的一半,向上彈出
this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);
arrow_up.setVisibility(View.GONE);
arrow_down.setVisibility(View.VISIBLE);
this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()); //顯示指定控件的上方
} else {
this.setAnimationStyle(R.style.operation_popwindow_anim_style_down); //反之向下彈出
arrow_up.setVisibility(View.VISIBLE);
arrow_down.setVisibility(View.GONE);
this.showAsDropDown(v, 0, 0); //顯示指定控件的下方
}
}
/**
* 顯示popupWindow 根據特殊要求高度顯示位置
*
* @param
*/
public void showPopupWindow(View v, View backgroundView,int hight) {
this.backgroundView = backgroundView;
v.getLocationOnScreen(location);
//獲取自身的長寬高
conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
backgroundView.setVisibility(View.VISIBLE);
//對view執行動畫
backgroundView.startAnimation(anim_backgroundView);
if (location[1] > MainApplication.SCREEN_H / 2 + 100) {
this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);
arrow_up.setVisibility(View.GONE);
arrow_down.setVisibility(View.VISIBLE);
this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()-hight);
} else {
this.setAnimationStyle(R.style.operation_popwindow_anim_style_down);
arrow_up.setVisibility(View.VISIBLE);
arrow_down.setVisibility(View.GONE);
this.showAsDropDown(v, 0, 0);
}
}
}
4.代碼中的用法
1.
CustomOperationPopWindow customOperationPopWindow = new CustomOperationPopWindow(this, operationTypeSelectlist);
customOperationPopWindow.setOnItemMyListener(new CustomOperationPopWindow.OnItemListener() {
@Override
public void OnItemListener(int position, TypeSelect typeSelect) {
//此處實現列表點擊所要進行的操作
}
});
2.
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
customOperationPopWindow.showPopupWindow(textView);//可以傳個半透明view v_background過去根據業務需要顯示隱藏
}
});
5.最終實際效果
以上代碼為幾乎主要全部代碼,主要是PopupWindow的用法,思路清晰一步一步實現很簡單。
MaterialRefreshLayout,swiperefreshlayout 以上就介紹了比SwipeRefreshLayout更漂亮和強大的下拉刷新控
Android官方文檔之Introduction 寫在前面的話:接觸Android的時間也不短了,聽了視頻、看了書、敲了代碼,寫了博客,做了demo。。。
初識genymotion安裝遇上的VirtualBox問題,genymotionvirtualbox 想必做過Android開發的
Android Studio下運行開源項目9GAG遇到的問題 首先是本地的build-tools版本不是開源項目所使用的,本來Android Studio點擊出錯提示