我正在开发新闻,并且在我的适配器类中,我的状态低于异常
埃德加,[20.10.19 13:50]
java.time.format.DateTimeParseException:文本'20 / 10/2019'无法 在索引0处解析 java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1948) 在 java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) 在java.time.LocalDateTime.parse(LocalDateTime.java:486)在 java.time.LocalDateTime.parse(LocalDateTime.java:471)在 yodgorbek.komilov.musobaqayangiliklari.adapter.BBCSportAdapter.onBindViewHolder(BBCSportAdapter.kt:83) 在 androidx.recyclerview.widget.RecyclerView $ Adapter.onBindViewHolder(RecyclerView.java:6781) 在 androidx.recyclerview.widget.RecyclerView $ Adapter.bindViewHolder(RecyclerView.java:6823) 在 androidx.recyclerview.widget.RecyclerView $ Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752) 在 androidx.recyclerview.widget.RecyclerView $ Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019) 在 androidx.recyclerview.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:5858) 在 androidx.recyclerview.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:5854) 在 androidx.recyclerview.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:2230) 在 androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557) 在 androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517) 在 androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612) 在 androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924) 在 androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3336) 在android.view.View.measure(View.java:22260) androidx.constraintlayout.widget.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227) 在 androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1572) 在android.view.View.measure(View.java:22260) android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185)在 android.view.View.measure(View.java:22260)在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185)在 android.view.View.measure(View.java:22260)在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185)在 androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143) 在android.view.View.measure(View.java:22260) android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在 androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:403) 在android.view.View.measure(View.java:22260) android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185)在 android.view.View.measure(View.java:22260)在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在 android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514) 在android.widget.LinearLayout.measureVertical(LinearLayout.java:806) 在android.widget.LinearLayout.onMeasure(LinearLayout.java:685) android.view.View.measure(View.java:22260)在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6686) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:185)在 com.android.internal.policy.DecorView.onMeasure(DecorView.java:728) 在android.view.View.measure(View.java:22260) android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2569)在 android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1594)在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1862) 在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1482)处 android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:7124) 在 android.view.Choreographer $ CallbackRecord.run(Choreographer.java:1008) 在android.view.Choreographer.doCallbacks(Choreographer.java:804)处 android.view.Choreographer.doFrame(Choreographer。
在MyAdapter类之下
class BBCSportAdapter(private val context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var articleList: List<Article> = listOf()
companion object {
const val urlKey = "urlKey"
const val imageUrl = "imageUrl"
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.bbc_sport_item, null)
return ViewHolder(view)
}
@SuppressLint("NewApi")
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as ViewHolder).apply {
when(position){
0 -> {
header.visibility = ViewGroup.VISIBLE
item.visibility = ViewGroup.GONE
Picasso.get().load(articleList[position].urlToImage)
.into(bigImage)
}
else -> {
header.visibility = ViewGroup.GONE
item.visibility = ViewGroup.VISIBLE
articleTitle.text = articleList[position].title
articleSourceName.text = articleList[position].source.name
Picasso.get().load(articleList[position].urlToImage).into(image)
val input = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.getDefault())
val output = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
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'", Locale.getDefault())
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()
val elapsedTime = Duration.between(timelinePoint, now)
println(timelinePoint)
println(now)
elapsedTime.toMinutes()
articleTime.text = "${elapsedTime.toMinutes()}"
holder.itemView.setOnClickListener { v->
val intent = Intent(v.context, DetailActivity::class.java)
intent.putExtra("urlKey", articleList[position].url)
intent.putExtra("imageUrl", articleList[position].urlToImage)
v.context.startActivity(intent)
}
}
}
}
}
}
}
override fun getItemCount(): Int {
return articleList.size
}
fun setMovieListItems(articleList: List<Article>) {
this.articleList = articleList
notifyDataSetChanged()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val image: ImageView = itemView.imageView
val articleTitle: TextView = itemView.articleTitle
val articleSourceName: TextView = itemView.articleSourceName
val imageCategory: ImageView = itemView.imageCategory
val articleTime: TextView = itemView.articleTime
val bigImage = itemView.bigImage
val header: CardView = itemView.header
val item: CardView = itemView.item
}
}
在Fragment类之下
class BBCSportFragment : Fragment() {
private val listViewType: List<Int> = listOf()
var bbcSportAdapter : BBCSportAdapter? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_sport_bbc, container, false)
val recyclerView = view.findViewById (R.id.recyclerView) as RecyclerView
bbcSportAdapter = BBCSportAdapter(recyclerView.context)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = bbcSportAdapter
val apiInterface = SportNewsInterface.create().getBBCSport()
// Getting interface
apiInterface.enqueue(object : Callback<SportNewsResponse> {
override fun onResponse(
call: Call<SportNewsResponse>?,
response: Response<SportNewsResponse>?
) {
if (response!!.body() != null) {
bbcSportAdapter!!.setMovieListItems(response.body()!!.articles)
}
}
override fun onFailure(call: Call<SportNewsResponse>?, t: Throwable?) {
}
})
return view
}
}
答案 0 :(得分:0)
我阅读代码的方式是收到一个publishedAt
字符串,该字符串看起来像2019-10-21T15:12:34+02
或2019-10-21T13:01:23Z
。如果您无法解析它,则您的代码将尝试使用从var d = Date()
获得的日期和时间,即当前时间。
只要您知道如何做,就可以轻松完成。抱歉,我只能编写Java代码。我需要相信你来翻译自己。
String publishedAt = "2019-10-21T13:01:23Z";
Instant timelinePoint;
try {
timelinePoint = DateTimeFormatter.ISO_OFFSET_DATE_TIME
.parse(publishedAt, Instant::from);
} catch (DateTimeParseException dtpe) {
timelinePoint = Instant.now();
}
Instant now = Instant.now();
Duration elapsedTime = Duration.between(timelinePoint, now);
System.out.println(timelinePoint);
System.out.println(now);
System.out.println(elapsedTime.toMinutes());
当我刚刚运行此代码段时,我得到了以下输出:
2019-10-21T13:01:23Z 2019-10-21T16:17:49.719Z 196
DateTimeFormatter.ISO_OFFSET_DATE_TIME
将解析您的字符串,无论偏移量是小时和可选分钟,还是Z
是零。因此,上述方法可以同时处理两种格式。
也没有任何理由将SimpleDateFormat
和Date
带入您的代码中。它只会使事情变得更复杂,却一无所获。同样,这些类的设计不佳,尤其是前者非常麻烦,而且过时了,因此,我强烈建议您清除它们,再也不要碰它们。
您使用的java.time中的LocalDateTime
类不是时间线上某个点的正确类。如果字符串中的偏移量与JVM默认时区的UTC偏移量不同,则您将获得LocalDateTime
个具有不同隐含偏移量的对象。这意味着比较它们是没有意义的,您将在它们之间花费不正确的时间。
对于您观察到的例外情况:如果您无法通过任何尝试解析字符串,则将当前日期和时间(从Date()
格式化为dd/MM/yyyy
格式,示例21/10/2019
,然后尝试使用单参数LocalDateTime.parse()
解析此字符串。这有几处错误。首先,parse
方法要求使用ISO 8601格式。该文档说:
从诸如以下的文本字符串中获取
LocalDateTime
的实例2007-12-03T10:15:30
。
您看到21/10/2019
和2007-12-03T10:15:30
的格式不相同。这就是您例外的原因。异常消息说at index 0
,因为字符串的索引0处是两位数字,并且该方法期望“一年中四位数或更多”(引自DateTimeFormatter.ISO_LOCAL_DATE
文档)。其次,您不想基于无日期的日期以分钟为单位测量经过时间。第三,您不能将没有日期的日期字符串解析为LocalDateTime
(有很多技巧,但是那样行不通)。