Android开发空间靠右放代码,Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果...

本文主要是介绍Android开发空间靠右放代码,Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们打开QQ空间的时候有个箭头按钮点击之后弹出PopupWindow会根据位置的变化显示在箭头的上方还是下方,比普通的PopupWindow弹在屏幕中间显示好看的多。

先看QQ空间效果图:

1fe809b6c49d62d2bc1fdb2f66fdb63c.pngedd63cf8f14bcd0bea4b1205695767a0.png

e0a1b0830d098a6fe441363bbc485914.png

这个要实现这个效果可以分几步进行

1.第一步自定义PopupWindow,实现如图的样式,这个继承PopupWindow自定义布局很容易实现

2.得到点击按钮的位置,根据位置是否在屏幕的中间的上方还是下方,将PopupWindow显示在控件的上方或者下方

2897382d8bb72635f1403592b4ab5826.png

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的布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:gravity="right">

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"/>

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">

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"/>

2.PopupWindow弹出动画以及消失动画

popshow_operation_anim_down.xml

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" >

popshow_operation_anim_up.xml

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" >

消失动画是渐隐动画可以自己定义,同理。

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 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 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 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.最终实际效果

5ab436b0f9f9e287347d90408ffb4d59.png

e2a41a85684a143354fec62cf76b0cb6.png

以上代码为几乎主要全部代码,主要是PopupWindow的用法,思路清晰一步一步实现很简单。

以上所述是小编给大家介绍的Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

这篇关于Android开发空间靠右放代码,Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/263667

相关文章

Python38个游戏开发库整理汇总

《Python38个游戏开发库整理汇总》文章介绍了多种Python游戏开发库,涵盖2D/3D游戏开发、多人游戏框架及视觉小说引擎,适合不同需求的开发者入门,强调跨平台支持与易用性,并鼓励读者交流反馈以... 目录PyGameCocos2dPySoyPyOgrepygletPanda3DBlenderFife

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre