adsl9002 2023-06-06 19:30 采纳率: 46.2%
浏览 64
已结题

Adapter里的布局id怎么引用

第一行代码第三版天气预告,在adapter里没法正常引用xml的id。

activity.weather.xml, 用于滑动显示子控件内容

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.weather.WeatherActivity">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ScrollView
            android:id="@+id/weatherLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:overScrollMode="never"
            android:scrollbars="none"
            android:visibility="invisible">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <include layout="@layout/now" />

                <include layout="@layout/forecast" />

                <include layout="@layout/life_index" />

            </LinearLayout>
        </ScrollView>
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:foregroundGravity="left"
        android:clickable="true"
        android:focusable="true"
        android:background="@color/colorPrimary">

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/placeFragment"
            android:name="com.example.sunnyweather2.ui.place.PlaceFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="25dp"/>

    </FrameLayout>

</androidx.drawerlayout.widget.DrawerLayout>

weatherActivity.kt 滑动菜单的逻辑,

package com.example.sunnyweather2.ui.weather

import android.content.Context
import android.icu.text.SimpleDateFormat
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.ScrollView
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.example.sunnyweather2.R
import com.example.sunnyweather2.logic.model.Weather
import com.example.sunnyweather2.logic.model.getSky
import java.util.Locale

class WeatherActivity : AppCompatActivity() {

    val viewModel by lazy {
        ViewModelProvider(this)[WeatherViewModel::class.java]
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_weather)

        val drawerLayout: DrawerLayout = findViewById(R.id.drawerLayout)
        val navBtn: Button = findViewById(R.id.navBtn)
        navBtn.setOnClickListener {
            drawerLayout.openDrawer(GravityCompat.START)
        }
        drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
            override fun onDrawerOpened(drawerView: View) {}
            override fun onDrawerStateChanged(newState: Int) {}
            override fun onDrawerClosed(drawerView: View) {
                val manager = getSystemService(Context.INPUT_METHOD_SERVICE)
                        as InputMethodManager
                manager.hideSoftInputFromWindow(
                    drawerView.windowToken,
                    InputMethodManager.HIDE_NOT_ALWAYS
                )
            }
        })

PlaceAdapter.kt 对PlaceFragment所处的activity进行判断,如果是在weatheractivity中,那关闭滑动菜单,给weatheractivity赋新值并刷新天气信息;如果是在mainactivity中,保持之前的处理逻辑不变,不过这里drawerLayout爆红,应该怎么处理。

我有试过在weatheracitvity把val drawerLayout: DrawerLayout = findViewById(R.id.drawerLayout)放在全局,drawerLayout虽然能正常写了,但运行起来就闪退,日志提示到findViewbyld这里错误

img

在if判断中添加实例,点击又没反应,

img

PlaceAdapter.kt

package com.example.sunnyweather2.ui.place

import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.example.sunnyweather2.MainActivity
import com.example.sunnyweather2.R
import com.example.sunnyweather2.logic.model.Place
import com.example.sunnyweather2.ui.weather.WeatherActivity

class PlaceAdapter(private val fragment: PlaceFragment, private val placeList: List<Place>) :
    RecyclerView.Adapter<PlaceAdapter.ViewHolder>() {

    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val placeName: TextView = view.findViewById(R.id.placeName)
        val placeAddress: TextView = view.findViewById(R.id.placeAddress)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(
            R.layout.place_item,
            parent, false
        )
        val holder = ViewHolder(view)

        holder.itemView.setOnClickListener {
            val position = holder.bindingAdapterPosition
            val place = placeList[position]
            val activity = fragment.activity

            if (activity is WeatherActivity) {
                activity.drawerLayout.closeDrawers()
                activity.viewModel.locationLng = place.location.lng
                activity.viewModel.locationLat = place.location.lat
                activity.viewModel.placeName = place.name
                activity.refreshWeather()
            } else {
                val intent = Intent(parent.context, WeatherActivity::class.java).apply {
                    putExtra("location_lng", place.location.lng)
                    putExtra("location_lat", place.location.lat)
                    putExtra("place_name", place.name)
                }
                fragment.startActivity(intent)
                fragment.activity?.finish()
            }
            fragment.viewModel.savePlace(place)
        }
        return holder
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val place = placeList[position]
        holder.placeName.text = place.name
        holder.placeAddress.text = place.address
    }

    override fun getItemCount() = placeList.size

}
  • 写回答

1条回答 默认 最新

  • IT论之程序员 2023-06-07 22:29
    关注
    Adapter里引用activity的布局id需要使用activity的上下文。你可以在Adapter的构造方法中接收一个上下文参数,然后使用findViewById来获取id:
    kotlin
    class PlaceAdapter(
        private val fragment: PlaceFragment, 
        private val placeList: List<Place>,
        private val context: Context  // 上下文参数
    ) : 
        RecyclerView.Adapter<PlaceAdapter.ViewHolder>() {
    
        inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            val placeName: TextView = view.findViewById(R.id.placeName)
            val placeAddress: TextView = view.findViewById(R.id.placeAddress)
            val drawerLayout: DrawerLayout = context.findViewById(R.id.drawerLayout)  // 使用上下文找到id
        }
    然后在创建Adapter的时候传入activity的上下文:
    kotlin
    val adapter = PlaceAdapter(placeFragment, viewModel.placeList, this)  // 传入this作为上下文
    这么做就可以在Adapter里正常使用activity的布局id了。
    你说的把drawerLayout定义为全局变量的方法有个问题,那样做会导致Activity的生命周期里的onDestory方法无法调用drawerLayout的清理方法,容易导致内存泄漏。所以最好的方法还是在Adapter中通过上下文参数获取activity的实例,而不是全局持有activity的实例。
    
    
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月29日
  • 修改了问题 6月8日
  • 创建了问题 6月6日

悬赏问题

  • ¥15 请问如何在openpcdet上对KITTI数据集的测试集进行结果评估?
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路
  • ¥15 phython读取excel表格报错 ^7个 SyntaxError: invalid syntax 语句报错