日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android使用 PopupWindow 實現底部彈窗功能

瀏覽:118日期:2022-09-21 10:44:24
一、知識點

不詳細展開 PopupWindow 或者視圖動畫的所有具體使用方式,僅僅介紹一下使用的一個大概流程和一些知識要點,具體的介紹在下面設計實現中講述

(一)PopupWindow

1. 初始化

加載彈窗的布局 實例化 PopupWindow 傳入布局和彈窗的寬高 對布局里面的控件的操作 對布局本身的一些設置

// 加載彈窗的布局pwView = LayoutInflater.from(this).inflate(R.layout.pw_search_engine, null, false)//實例化 PopupWindowpopupWindow = PopupWindow( pwView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)// 對布局里面的控件的操作initRecyclerView()// 對布局本身的一些設置popupWindow.isOutsideTouchable = truepopupWindow.isTouchable = truepopupWindow.isFocusable = truepopupWindow.animationStyle = R.style.pw_bottom_anim_stylepopupWindow.setOnDismissListener { backgroundAlpha(1f)}

2. 展示彈窗

彈出彈窗修改背景亮度—變暗

// 彈出彈窗val rootView = LayoutInflater.from(this).inflate(R.layout.activity_main,null)popupWindow.showAtLocation(rootView, Gravity.BOTTOM, 0, 0)// 修改背景亮度—變暗backgroundAlpha(0.7f)

3. 關閉彈窗

關閉彈窗 修改背景亮度—變亮

// 關閉彈窗popupWindow.dismiss() // 修改背景亮度—變亮backgroundAlpha(1f)

4. 背景亮度修改

// 控制背景亮度private fun backgroundAlpha(bgAlpha: Float) { val lp = window.attributes lp.alpha = bgAlpha //0.0-1.0 window.attributes = lp}(二)視圖動畫

使用 XML 標簽定義并使用視圖動畫:

1. XML 標簽

alpha 漸變透明度 scale 漸變尺寸伸縮 translate 畫面位置移動 rotate 畫面轉移旋轉 set 定義動畫集

2. 給 PopupWindow 添加動畫

popupWindow.animationStyle = R.style.pw_bottom_anim_style二、界面效果

Android使用 PopupWindow 實現底部彈窗功能

三、設計實現(一)需求分析 點擊主頁按鈕彈出底部彈窗 點擊彈窗引擎,以Toast顯示引擎名稱并關閉彈窗 點擊彈窗外部可以關閉彈窗(二)文件列表

Android使用 PopupWindow 實現底部彈窗功能

(三)布局設計

1. 主界面樣式設計

(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:orientation='vertical' tools:context='.MainActivity'> <Button android: android:layout_width='match_parent' android:layout_height='wrap_content' android:layout_margin='14dp' android:text='點擊——底部彈窗' android:textColor='@color/white'/></LinearLayout>

2. 彈窗樣式設計

(pw_search_engine.xml)

彈窗樣式的布局也十分簡單,就是一個基本的線性布局的 RecyclerView值得注意的是,最基本的 layoutManager 可以通過指定 app:layoutManager 來實現

<?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' android:orientation='vertical' android:layout_width='match_parent' android:layout_height='wrap_content' android:background='@color/white'> <androidx.recyclerview.widget.RecyclerView android: android:layout_width='match_parent' android:layout_height='wrap_content' android:overScrollMode='never' app:layoutManager='androidx.recyclerview.widget.LinearLayoutManager' /></LinearLayout>

3. 彈窗列表 item 樣式設計

(item_search_engine.xml)

列表單項,因為是 Demo 示例,所以簡單地用一個橫向布局,內置一個圖標 icon 和一個名稱 TextView 來進行展示

<?xml version='1.0' encoding='utf-8'?><LinearLayout xmlns:android='http://schemas.android.com/apk/res/android' android:orientation='horizontal' android:layout_width='match_parent' android:layout_height='wrap_content' android:gravity='center'> <ImageView android: android:layout_width='36dp' android:layout_height='36dp' android:layout_margin='14dp' /> <TextView android: android:layout_width='0dp' android:layout_height='wrap_content' android:layout_weight='1' android:layout_marginEnd='36dp' android:maxLines='1' android:ellipsize = 'end' android:textColor='@color/black' android:textSize='16sp' /></LinearLayout>

4. 彈窗動畫設計

(pw_bottom_in.xml 與 pw_bottom_out.xml)

<!--pw_bottom_in.xml--><?xml version='1.0' encoding='utf-8'?><set xmlns:android='http://schemas.android.com/apk/res/android'> <!-- 平移動畫 duration--動畫持續時間 android:fromXDelta,android:fromYDelta--起始 x,y android:toXDelta,android:toYDelta--終點 x,y --> <translate android:duration='300' android:fromXDelta='0' android:fromYDelta='1000' android:toXDelta='0' android:toYDelta='0' /></set><!--pw_bottom_out.xml--><?xml version='1.0' encoding='utf-8'?><set xmlns:android='http://schemas.android.com/apk/res/android'> <translate android:duration='300' android:fromXDelta='0' android:fromYDelta='0' android:toXDelta='0' android:toYDelta='1000' /></set>(四)數據存儲與加載

1. 數據存儲(UIData.kt 與 arrays.xml)

// 搜索引擎的數據實體類,包含名稱和 icon 資源 id 兩個屬性data class SearchEngine( val title : String, val res : Int)

以字符串數組的形式存儲搜索引擎的名稱以及對應的圖標資源

<?xml version='1.0' encoding='utf-8'?><resources> <string-array name='search_engine_title_list'> <item>百度</item> <item>搜狗</item> <item>360</item> <item>必應</item> <item>神馬</item> </string-array> <string-array name='search_engine_res_list'> <item>@drawable/ic_baidu</item> <item>@drawable/ic_sougou</item> <item>@drawable/ic_360</item> <item>@drawable/ic_bing</item> <item>@drawable/ic_shenma</item> </string-array></resources>

2. 數據加載(MainActivity.kt)

private lateinit var engines : MutableList<SearchEngine>private fun initData() {// 初始化引擎列表 engines = mutableListOf()// 從 arrays.xml 獲取引擎名稱數組 val titleList = resources.getStringArray(R.array.search_engine_title_list)// 由于資源 id 是整型,但是在 arrays.xml 中存儲的是字符串,// 所以這里先初始化一個資源 id 的數組,元素類型為整型 val iconResList : MutableList<Int> = mutableListOf() // 通過類型數組加載相關引擎資源列表,遍歷其中元素,傳入索引值, // 通過調用 getResourceId(index,0) 獲取 icon 的資源 id 存入剛才初始化的 id 數組中 val resList: TypedArray = resources.obtainTypedArray(R.array.search_engine_res_list) for (index in 0 until resList.length()) { iconResList.add(resList.getResourceId(index,0)) } // 記得及時調用 recycle() 回收 TypedArray 對象 resList.recycle()// 循環,用獲得的 title 和 id 生成對應的搜索引擎對象,存入搜索引擎列表中 for (index in titleList.indices){ if (index < iconResList.size){ engines.add(SearchEngine(titleList[index],iconResList[index])) } }}(五)剩余內容

上述提及的內容代碼,此處將不再進行展示;因為重點是介紹底部彈窗的實現,彈窗布局中的 RecyclerView 的實現就不過多介紹

1. AdapterForSearchEngine.kt 彈窗列表適配器

class AdapterForSearchEngine (dataList: MutableList<SearchEngine>) : RecyclerView.Adapter<AdapterForSearchEngine.ViewHolder>() { // 搜索引擎數據集合 private val mDataList: MutableList<SearchEngine> = mutableListOf() init { // 初始化 主要是對數據進行初始化 mDataList.clear() mDataList.addAll(dataList) } // ViewHolder 方便 item 復用 class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {} // 獲取列表 item 數量 override fun getItemCount(): Int { return mDataList.size } // 綁定視圖與數據 override fun onBindViewHolder(holder: ViewHolder, position: Int) { val engine: SearchEngine = mDataList[position] holder.itemView.titleTV.text = engine.title holder.itemView.iconIV.setImageResource(engine.res) holder.itemView.setOnClickListener { listener?.click(engine) } } // 創建 ViewHolder 實例 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view: View = LayoutInflater.from(parent.context).inflate(R.layout.item_search_engine, parent, false) return ViewHolder(view) } // 點擊事件 private var listener :OnItemClickListener? = null interface OnItemClickListener { fun click(engine: SearchEngine) } fun setOnItemClickListener(listener: OnItemClickListener) { this.listener = listener }}

2. MainActivity.kt

class MainActivity : AppCompatActivity() { private lateinit var engines : MutableList<SearchEngine> private lateinit var popupWindow : PopupWindow private lateinit var pwView : View private lateinit var mAdapter : AdapterForSearchEngine override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化數據 initData() // 初始化 PopupWindow initPopupWindow() // 按鈕點擊事件 btn.setOnClickListener { // 顯示彈窗 showPopWindow() } } private fun initPopupWindow() { // 加載彈窗布局 pwView = LayoutInflater.from(this).inflate(R.layout.pw_search_engine, null, false) // 實例化 PopupWindow popupWindow = PopupWindow( pwView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) // 初始化彈窗列表 initRecyclerView() // 設置 popupWindow popupWindow.isOutsideTouchable = true popupWindow.isTouchable = true popupWindow.isFocusable = true // 加載彈窗動畫 popupWindow.animationStyle = R.style.pw_bottom_anim_style // 設置彈窗關閉監聽——恢復亮度 popupWindow.setOnDismissListener { backgroundAlpha(1f) } } private fun showPopWindow() { val rootView = LayoutInflater.from(this).inflate( R.layout.activity_main, null ) // 設置彈窗位置 popupWindow.showAtLocation(rootView, Gravity.BOTTOM, 0, 0) // 使得背景亮度變暗 backgroundAlpha(0.7f) } // 控制背景亮度 private fun backgroundAlpha(bgAlpha: Float) { val lp = window.attributes lp.alpha = bgAlpha //0.0-1.0 window.attributes = lp } private fun initRecyclerView() { mAdapter = AdapterForSearchEngine(engines) pwView.recyclerView?.adapter = mAdapter mAdapter.setOnItemClickListener(object : AdapterForSearchEngine.OnItemClickListener{ override fun click(engine: SearchEngine) { Toast.makeText(this@MainActivity, engine.title, Toast.LENGTH_SHORT).show() popupWindow.dismiss() } }) } private fun initData() { // 初始化引擎列表 engines = mutableListOf() // 從 arrays.xml 獲取引擎名稱數組 val titleList = resources.getStringArray(R.array.search_engine_title_list) // 由于資源 id 是整型,但是在 arrays.xml 中存儲的是字符串, // 所以這里先初始化一個資源 id 的數組,元素類型為整型 val iconResList : MutableList<Int> = mutableListOf() // 通過類型數組加載相關引擎資源列表,遍歷其中元素,傳入索引值, // 通過調用 getResourceId(index,0) 獲取 icon 的資源 id 存入剛才初始化的 id 數組中 val resList: TypedArray = resources.obtainTypedArray(R.array.search_engine_res_list) for (index in 0 until resList.length()) { iconResList.add(resList.getResourceId(index,0)) } // 記得及時調用 recycle() 回收 TypedArray 對象 resList.recycle() // 循環,用獲得的 title 和 id 生成對應的搜索引擎對象,存入搜索引擎列表中 for (index in titleList.indices){ if (index < iconResList.size){ engines.add(SearchEngine(titleList[index],iconResList[index])) } } }}

到此這篇關于Android使用 PopupWindow 實現底部彈窗功能的文章就介紹到這了,更多相關Android PopupWindow底部彈窗內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久av国产紧身裤| 另类中文字幕国产精品| 五月天激情综合网| 国精品一区二区| 欧美日韩国产观看视频| 久久精品日韩欧美| 电影91久久久| 精品国产乱码久久久久久1区2匹| 久久一区国产| 国产66精品| 日韩大片免费观看| 91青青国产在线观看精品| 久久亚洲精精品中文字幕| 日本久久精品| 久久在线免费| 中文一区在线| 亚洲精品影院在线观看| 亚洲色图国产| 日韩av成人高清| 鲁大师精品99久久久| 伊人久久国产| 国产精品7m凸凹视频分类| 男女性色大片免费观看一区二区| 亚洲欧美网站在线观看| 欧美精品影院| 精品一二三区| 日韩不卡免费高清视频| 久久精品av| 久久国产88| 欧美日韩va| 福利欧美精品在线| 在线视频观看日韩| 蜜桃91丨九色丨蝌蚪91桃色| 青青草91视频| 中文一区一区三区高中清不卡免费| 国产一区清纯| 奇米狠狠一区二区三区| 精品视频亚洲| 99久久久久久中文字幕一区| 老牛影视一区二区三区| 奇米亚洲欧美| 国产精选在线| 精品日韩毛片| 亚洲区欧美区| 久久精品国产成人一区二区三区| 久久久水蜜桃av免费网站| 亚洲欧美日韩专区| 欧美日韩1区| 国产欧美一区二区三区精品酒店| 国内激情久久| 日韩黄色在线观看| 欧美丰满日韩| 亚洲视频国产| 精品美女视频 | 国产精品a久久久久| 精品国产成人| 美女被久久久| 精品高清久久| 爽好多水快深点欧美视频| 久久亚洲国产精品尤物| 欧美在线亚洲| 久久这里只有| 亚洲一区二区免费看| 精品三级在线| 在线精品一区| 中文字幕人成乱码在线观看| 久久午夜影视| 精品三区视频| 蜜桃av一区二区| 日韩伦理一区| 亚洲青青久久| 91精品啪在线观看国产18| 欧美一区91| 99热精品在线观看| 久久精品一区二区国产| 中文字幕一区二区三区日韩精品 | 美女视频网站久久| 免费看黄色91| 在线一区av| 国产亚洲欧美日韩在线观看一区二区 | 欧美天堂在线| 午夜电影亚洲| 国产一区二区三区日韩精品| 亚洲精品观看| 亚洲精品极品少妇16p| 高清久久一区| 欧美专区一区| 中文字幕一区二区三区日韩精品| 久久在线免费| 精品国产亚洲日本| 亚洲开心激情| 五月精品视频| 日韩久久一区二区三区| 欧美国产中文高清| 伊人国产精品| 午夜在线精品| 欧美日韩国产综合网| 精精国产xxxx视频在线播放| 国产精品久久久久久久久久久久久久久 | 欧美精品黄色| 麻豆精品蜜桃| av中文资源在线资源免费观看| 日韩国产一区二| 最新日韩av| 婷婷激情久久| 日韩中文影院| 四季av一区二区凹凸精品| 欧美午夜网站| 亚洲1区在线| 一本色道久久精品| 久久中文字幕av一区二区不卡| 国产精品黄网站| 91精品啪在线观看国产爱臀| 免费观看在线综合色| 激情综合自拍| 亚洲高清不卡| 欧美成人国产| 久久久久国产| 婷婷综合六月| 日韩中文欧美| 在线一区视频观看| 日韩欧美精品| 国产高潮在线| 麻豆视频在线观看免费网站黄| 国产高清亚洲| 麻豆国产欧美日韩综合精品二区| 88久久精品| 欧美日韩1区2区3区| 日韩欧美四区| 日本精品在线播放| 欧美三级第一页| 国产亚洲一卡2卡3卡4卡新区| 欧美日韩一区二区三区四区在线观看| 色8久久久久| 69堂精品视频在线播放| 国产伦理一区| 高潮久久久久久久久久久久久久| 国产一区2区| 久久毛片亚洲| 久久人人99| 亚洲激情欧美| 美女精品在线| 日韩av午夜在线观看| 国产日韩在线观看视频| 久久99久久久精品欧美| 日本激情一区| 欧美色图一区| 亚洲午夜久久| 国产日韩视频在线| 欧美a在线观看| 97精品在线| 亚洲男女av一区二区| 在线亚洲人成| 日韩在线卡一卡二| 欧美黑人做爰爽爽爽| 国语精品一区| 午夜在线一区二区| 日韩一区二区三区四区五区| 国产一区二区三区不卡视频网站 | 九色精品91| 日韩精品福利一区二区三区| 国产欧美另类| 在线亚洲免费| 免费看av不卡| 国产日韩欧美一区二区三区在线观看 | 四虎成人av| 日韩av成人高清| 日本一不卡视频| 91精品一区二区三区综合| 国产精品毛片| 日韩黄色在线观看| 五月天激情综合网| 免费久久精品视频| 亚洲在线久久| 欧美黄页在线免费观看| 久久久精品五月天| 日韩精品视频网站| 国产一区二区三区日韩精品| 国产精品日本| 日韩高清一区| 免费高清在线一区| 欧美.日韩.国产.一区.二区| 欧美1区2区3| 国产日产精品_国产精品毛片 | 免费看av不卡| 91精品国产自产精品男人的天堂| 精品一区二区三区四区五区| 国产精品最新自拍| 国产精品亲子伦av一区二区三区| 99热精品在线观看| 一本色道精品久久一区二区三区| 午夜在线一区二区| 中文无码久久精品| 欧美亚洲一区二区三区| 国产精品国产三级在线观看| 国产欧美综合一区二区三区| 亚洲欧美日韩精品一区二区| 久久精品女人| 国产精品一区2区3区| 欧美在线精品一区|