【问题标题】:why bottom navigation drawer fragment showing empty data为什么底部导航抽屉片段显示空数据
【发布时间】:2019-10-09 21:09:34
【问题描述】:

我正在开发新闻应用程序,我创建了带有片段的底部导航,在 topheadlinesfragment 中我正在使用改造获取新闻数据,但它显示空白屏幕 以下 empty white screen

在我的 MainActivity_kt 下方,我用片段实现了底部导航抽屉

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

       val  bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom)



        bottomNavigationView.setOnNavigationItemSelectedListener {

            var selectedFragment = Fragment()
            when (it.itemId) {
                R.id.top_headline -> selectedFragment = TopHeadlinesFragment()

                R.id.espn_news -> selectedFragment = ESPNFragment()
                R.id.bbc_sport -> selectedFragment = BBCSportFragment()
                R.id.football_italia -> selectedFragment = FootballItaliaFragment()
            }
            val transaction = supportFragmentManager.beginTransaction()
            transaction.replace(R.id.frame_layout, selectedFragment)
            transaction.commit()
            return@setOnNavigationItemSelectedListener true

        }
    }
}

在activity_main.xml下面

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_gravity="bottom"
        app:menu="@menu/bottomnews_nav"
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</FrameLayout>

在我的 TopHeadlinesAdapter 下方

@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class TopHeadlinesAdapter(val context: Context) :
    RecyclerView.Adapter<TopHeadlinesAdapter.MyViewHolder>() {

    var articleList: List<Article> = listOf()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

        val view = LayoutInflater.from(parent.context).inflate(R.layout.news_list, parent, false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int {
        return articleList.size
    }

    @SuppressLint("NewApi")
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

        holder.articleTitle.text = articleList.get(position).title
        holder.articleSourceName.text = articleList.get(position).source.name
        Picasso.get().load(articleList.get(position).urlToImage).into(holder.image)

        val input = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX")
        val output = SimpleDateFormat("dd/MM/yyyy")
        var d = Date()
        try {
            d = input.parse(articleList[5].publishedAt)
        } catch (e: ParseException) {
            try {
                val fallback = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
                fallback.timeZone = TimeZone.getTimeZone("UTC")
                d = fallback.parse(articleList[5].publishedAt)
            } catch (e2: ParseException) {
                // TODO handle error
                val formatted = output.format(d)
                val timelinePoint = LocalDateTime.parse(formatted)
                val now = LocalDateTime.now()

                var elapsedTime = Duration.between(timelinePoint, now)

                println(timelinePoint)
                println(now)
                elapsedTime.toMinutes()

                holder.articleTime.text = "${elapsedTime.toMinutes()}"

            }
        }

    }

    fun setMovieListItems(articleList: List<Article>) {
        this.articleList = articleList
        notifyDataSetChanged()
    }

    @SuppressLint("NewApi")
    fun example() {
    }

    class MyViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {

        val image: ImageView = itemView!!.findViewById(R.id.imageView)
        val articleTitle: TextView = itemView!!.findViewById(R.id.articleTitle)
        val articleSourceName: TextView = itemView!!.findViewById(R.id.articleSourceName)
        val imageCategory: ImageView = itemView!!.findViewById(R.id.imageCategory)
        val articleTime: TextView = itemView!!.findViewById(R.id.articleTime)

    }
}

在 news_list.xml 下方

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="100dp"
            android:layout_height="85dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:contentDescription="bbc"
            tools:background="@color/colorPrimary" />

        <TextView
            android:id="@+id/articleTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:layout_toEndOf="@id/imageView"
            android:layout_toRightOf="@id/imageView"
            android:ellipsize="end"
            android:lines="3"
            android:maxLines="3"
            android:text="1\n2\n3\n" />

        <ImageView
            android:id="@+id/imageCategory"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_below="@id/articleTitle"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_toEndOf="@id/imageView"
            android:layout_toRightOf="@id/imageView"
            android:src="@drawable/ic_espn"
            tools:background="@color/colorPrimary" />

        <TextView
            android:id="@+id/articleSourceName"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:layout_below="@id/articleTitle"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_toEndOf="@id/imageCategory"
            android:layout_toRightOf="@id/imageCategory"
            android:gravity="center|start"
            android:text="Onefootbal" />

        <TextView
            android:id="@+id/articleTime"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:layout_below="@id/articleTitle"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:layout_toEndOf="@id/articleSourceName"
            android:layout_toRightOf="@id/articleSourceName"
            android:gravity="center|start"
            android:text="- 1h"
            android:textColor="@android:color/darker_gray"
            tools:ignore="NotSibling" />
    </RelativeLayout>

</androidx.cardview.widget.CardView>

在我使用改造获取新闻数据的 TopHeadlinesFragment 下方

class TopHeadlinesFragment : Fragment() {
    var topHeadlinesAdapter: TopHeadlinesAdapter? = null

    //3
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view =  inflater.inflate(
            R.layout.fragment_top_headlines
            , container, false
        )

       val recyclerView = view.findViewById (R.id.recyclerView) as RecyclerView
        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = topHeadlinesAdapter


        val apiInterface = SportNewsInterface.create().getNews()


        apiInterface.enqueue(object : Callback<SportNewsResponse> {
            override fun onResponse(
                call: Call<SportNewsResponse>?,
                response: Response<SportNewsResponse>?
            ) {

                if (response?.body() != null) topHeadlinesAdapter?.setMovieListItems(response.body()!!.articles)
            }

            override fun onFailure(call: Call<SportNewsResponse>?, t: Throwable?) {

            }
        })
        return view
    }
}

fragment_top_headlines.xml 下方

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在我的日志猫下面

2019-10-10 15:23:07.818 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout
2019-10-10 15:23:08.324 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout
2019-10-10 15:23:09.497 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout
2019-10-10 15:23:12.277 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout
2019-10-10 15:23:14.761 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout
2019-10-10 15:23:21.146 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout
2019-10-10 15:23:21.452 27558-27558/yodgorbek.komilov.musobaqayangiliklari E/RecyclerView: No adapter attached; skipping layout

【问题讨论】:

  • 您是否收到任何异常或警告?您收到 API 的响应了吗?
  • Maor Hadad 我收到来自我使用邮递员检查的 api 的响应
  • 还为片段添加一个容器。 frame_layout 是主布局,在其中添加一个新的 framelayout 以包含片段
  • 但是你在你的应用程序中得到了它吗?请验证它。如果您将代码上传到 bitbucket 或 github 会很有帮助,这样我也可以运行它
  • 你的意思是我不明白的内部片段

标签: android android-fragments android-recyclerview bottomnavigationview


【解决方案1】:

"E/RecyclerView: 未连接适配器;"你没有初始化你的适配器。

我不确定它是否能解决您的问题,但首先将布局更改为:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout 
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_gravity="bottom"
        app:menu="@menu/bottomnews_nav"
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</FrameLayout>

【讨论】:

  • 我已添加日志@MaorHadad 请检查一下
【解决方案2】:

您的问题是您的 recyclerview 没有在 Top Headlines 上首字母缩写。
TopHeadlinesFragment上替换此代码

class TopHeadlinesFragment : Fragment() {
    var topHeadlinesAdapter: TopHeadlinesAdapter? = null

    //3
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view =  inflater.inflate(
            R.layout.fragment_top_headlines
            , container, false
        )

       val recyclerView = view.findViewById (R.id.recyclerView) as RecyclerView
        topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context)

        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = topHeadlinesAdapter


        val apiInterface = SportNewsInterface.create().getNews()


        apiInterface.enqueue(object : Callback<SportNewsResponse> {
            override fun onResponse(
                call: Call<SportNewsResponse>?,
                response: Response<SportNewsResponse>?
            ) {

                if (response!!.body() != null) {
                    topHeadlinesAdapter!!.setMovieListItems(response.body()!!.articles)
                }
            }

            override fun onFailure(call: Call<SportNewsResponse>?, t: Throwable?) {

            }
        })
        return view
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    相关资源
    最近更新 更多