最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android使用 PopupWindow 實現(xiàn)底部彈窗功能

 更新時間:2020年12月30日 11:24:53   作者:Nicholas_hzf  
這篇文章主要介紹了Android使用 PopupWindow 實現(xiàn)底部彈窗功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、知識點

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

(一)PopupWindow

1. 初始化

  • 加載彈窗的布局
  • 實例化 PopupWindow 傳入布局和彈窗的寬高
  • 對布局里面的控件的操作
  • 對布局本身的一些設(shè)置
// 加載彈窗的布局
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()
// 對布局本身的一些設(shè)置
popupWindow.isOutsideTouchable = true
popupWindow.isTouchable = true
popupWindow.isFocusable = true
popupWindow.animationStyle = R.style.pw_bottom_anim_style
popupWindow.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. 關(guān)閉彈窗

  • 關(guān)閉彈窗
  • 修改背景亮度—變亮
// 關(guān)閉彈窗
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 畫面轉(zhuǎn)移旋轉(zhuǎn)
  • set 定義動畫集

2. 給 PopupWindow 添加動畫

popupWindow.animationStyle = R.style.pw_bottom_anim_style

二、界面效果

底部彈窗

三、設(shè)計實現(xiàn)

(一)需求分析

  • 點擊主頁按鈕彈出底部彈窗
  • 點擊彈窗引擎,以Toast顯示引擎名稱并關(guān)閉彈窗
  • 點擊彈窗外部可以關(guān)閉彈窗

(二)文件列表

文件列表

(三)布局設(shè)計

1. 主界面樣式設(shè)計

(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:id="@+id/btn"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_margin="14dp"
  android:text="點擊——底部彈窗"
  android:textColor="@color/white"/>

</LinearLayout>

2. 彈窗樣式設(shè)計

(pw_search_engine.xml)

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

<?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:id="@+id/recyclerView"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:overScrollMode="never"
  app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</LinearLayout>

3. 彈窗列表 item 樣式設(shè)計

(item_search_engine.xml)

列表單項,因為是 Demo 示例,所以簡單地用一個橫向布局,內(nèi)置一個圖標 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:id="@+id/iconIV"
  android:layout_width="36dp"
  android:layout_height="36dp"
  android:layout_margin="14dp" />
  
 <TextView
  android:id="@+id/titleTV"
  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. 彈窗動畫設(shè)計

(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--動畫持續(xù)時間
  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>

(四)數(shù)據(jù)存儲與加載

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

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

以字符串數(shù)組的形式存儲搜索引擎的名稱以及對應(yīng)的圖標資源

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string-array name="search_engine_title_list">
  <item>百度</item>
  <item>搜狗</item>
  <item>360</item>
  <item>必應(yīng)</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. 數(shù)據(jù)加載(MainActivity.kt)

private lateinit var engines : MutableList<SearchEngine>

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

(五)剩余內(nèi)容

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

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

class AdapterForSearchEngine (dataList: MutableList<SearchEngine>) :
  RecyclerView.Adapter<AdapterForSearchEngine.ViewHolder>() {

 // 搜索引擎數(shù)據(jù)集合
 private val mDataList: MutableList<SearchEngine> = mutableListOf()

 init {
  // 初始化 主要是對數(shù)據(jù)進行初始化
  mDataList.clear()
  mDataList.addAll(dataList)
 }

 // ViewHolder 方便 item 復(fù)用
 class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {}

 // 獲取列表 item 數(shù)量
 override fun getItemCount(): Int {
  return mDataList.size
 }
 
 // 綁定視圖與數(shù)據(jù)
 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)
  }
 }

 // 創(chuàng)建 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)
  // 初始化數(shù)據(jù)
  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()
  // 設(shè)置 popupWindow
  popupWindow.isOutsideTouchable = true
  popupWindow.isTouchable = true
  popupWindow.isFocusable = true
  // 加載彈窗動畫
  popupWindow.animationStyle = R.style.pw_bottom_anim_style
  // 設(shè)置彈窗關(guān)閉監(jiān)聽——恢復(fù)亮度
  popupWindow.setOnDismissListener {
   backgroundAlpha(1f)
  }
 }

 private fun showPopWindow() {
  val rootView = LayoutInflater.from(this).inflate(
    R.layout.activity_main,
    null
  )
  // 設(shè)置彈窗位置
  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 獲取引擎名稱數(shù)組
  val titleList = resources.getStringArray(R.array.search_engine_title_list)
  // 由于資源 id 是整型,但是在 arrays.xml 中存儲的是字符串,
  // 所以這里先初始化一個資源 id 的數(shù)組,元素類型為整型
  val iconResList : MutableList<Int> = mutableListOf()
  // 通過類型數(shù)組加載相關(guān)引擎資源列表,遍歷其中元素,傳入索引值,
  // 通過調(diào)用 getResourceId(index,0) 獲取 icon 的資源 id 存入剛才初始化的 id 數(shù)組中
  val resList: TypedArray =
    resources.obtainTypedArray(R.array.search_engine_res_list)
  for (index in 0 until resList.length()) {
   iconResList.add(resList.getResourceId(index,0))
  }
  // 記得及時調(diào)用 recycle() 回收 TypedArray 對象
  resList.recycle()
  // 循環(huán),用獲得的 title 和 id 生成對應(yīng)的搜索引擎對象,存入搜索引擎列表中
  for (index in titleList.indices){
   if (index < iconResList.size){
    engines.add(SearchEngine(titleList[index],iconResList[index]))
   }
  }
 }

}

到此這篇關(guān)于Android使用 PopupWindow 實現(xiàn)底部彈窗功能的文章就介紹到這了,更多相關(guān)Android PopupWindow底部彈窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • android初學者必須掌握的Activity狀態(tài)的四大知識點(必讀)

    android初學者必須掌握的Activity狀態(tài)的四大知識點(必讀)

    本篇文章主要介紹了android activity的四種狀態(tài),詳細的介紹了四種狀態(tài),包括Running狀態(tài)、Paused狀態(tài)、Stopped狀態(tài)、Killed狀態(tài),有興趣的可以了解一下。
    2016-11-11
  • Android仿XListView支持下拉刷新和上劃加載更多的自定義RecyclerView

    Android仿XListView支持下拉刷新和上劃加載更多的自定義RecyclerView

    這篇文章主要介紹了仿XListView支持下拉刷新和上劃加載更多的自定義RecyclerView的實例代碼,非常不錯,具有參考價值,感興趣的朋友可以參考下
    2016-05-05
  • Android多返回棧技術(shù)

    Android多返回棧技術(shù)

    本文將詳情講解用戶通過系統(tǒng)返回按鈕導(dǎo)航回去的一組頁面,在開發(fā)中被稱為返回棧 (back stack)。多返回棧即一堆 "返回棧",對多返回棧的支持是在 Navigation 2.4.0-alpha01 和 Fragment 1.4.0-alpha01 中開始的,有興趣的話一起參與學習
    2021-08-08
  • Android 10.0截屏流程詳解

    Android 10.0截屏流程詳解

    這篇文章主要為大家介紹了Android 10.0截屏流程詳解,通常未通過特殊定制的 Android 系統(tǒng),截屏都是經(jīng)過同時按住音量下鍵和電源鍵來截屏,本篇文章就只討論使用這些特殊按鍵來進行截屏
    2023-06-06
  • Android 啟動 Service(startservice和bindservice) 兩種方式的區(qū)別

    Android 啟動 Service(startservice和bindservice) 兩種方式的區(qū)別

    andrid service 兩種啟動方式:第一種startservice,第二種bindservice,大家對這兩種啟動方式的區(qū)別了解嗎,下面跟著小編一起學習吧
    2015-11-11
  • Android開源項目PullToRefresh下拉刷新功能詳解

    Android開源項目PullToRefresh下拉刷新功能詳解

    這篇文章主要為大家詳細介紹了Android開源項目PullToRefresh下拉刷新功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Android adb 出錯解決方法

    Android adb 出錯解決方法

    本文主要介紹Android 中的adb,相信大家在開發(fā)過程中經(jīng)常使用adb進行調(diào)試,這里主要說明adb 出錯問題解決方法,希望能幫助有需要的同學
    2016-07-07
  • Android?中的?Timer?和?TimerTask詳解

    Android?中的?Timer?和?TimerTask詳解

    Timer?是?Java?中用于創(chuàng)建定時任務(wù)的類,它位于?java.util?包中,可以使用Timer來安排一次性或定期執(zhí)行的任務(wù),這篇文章主要介紹了Android?的?Timer?和?TimerTask,需要的朋友可以參考下
    2024-05-05
  • Android簡易圖片瀏覽器的實現(xiàn)

    Android簡易圖片瀏覽器的實現(xiàn)

    最近做了一個圖片瀏覽小程序,本文主要介紹了Android簡易圖片瀏覽器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-03-03
  • Android Studio實現(xiàn)井字游戲

    Android Studio實現(xiàn)井字游戲

    這篇文章主要為大家詳細介紹了Android Studio實現(xiàn)井字游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

体育| 宜良县| 叶城县| 朝阳区| 石楼县| 永和县| 若尔盖县| 宝应县| 宜丰县| 睢宁县| 翁牛特旗| 伊金霍洛旗| 白沙| 巴里| 甘德县| 湘潭市| 长丰县| 乌兰浩特市| 新河县| 红原县| 榆林市| 介休市| 谢通门县| 濮阳县| 普兰县| 静乐县| 蛟河市| 犍为县| 龙游县| 聊城市| 信宜市| 满洲里市| 红安县| 祁连县| 清丰县| 吉安县| 黄陵县| 广水市| 惠州市| 霍山县| 关岭|