首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从网格RecyclerView到细节活动的共享转换效果

从网格RecyclerView到细节活动的共享转换效果
EN

Stack Overflow用户
提问于 2018-10-08 13:37:46
回答 1查看 1.2K关注 0票数 0

我正在尝试在具有网格布局的RecyclerView之间进行第一次共享转换,以实现细节活动。

代码语言:javascript
复制
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_cryptocurrencies"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    android:overScrollMode="never" />

首先,transitionName在细节布局和RecyclerView布局中都被设置为"cryptocurrency_name“。

代码语言:javascript
复制
<!-- RecyclerView's item layout -->
<TextView
    style="@style/CurrencyTextView"
    android:id="@+id/tv_cryptocurrency_name"
    android:textSize="20sp"
    android:maxLength="12"
    android:transitionName="cryptocurrency_name"
    tools:text="Bitcoin" />

...
<!-- Details -->
<TextView
    android:id="@+id/tv_cryptocurrency_detail_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Bitcoin"
    android:textSize="32sp"
    android:transitionName="cryptocurrency_name"
    .../>

MainActivity从适配器中重写的方法:

代码语言:javascript
复制
private var tvCryptocurrencyName: TextView? = null
tvCryptocurrencyName = rv_cryptocurrencies.findViewById(R.id.tv_cryptocurrency_name)

override fun onItemClick(cryptocurrency: Cryptocurrency) {
    val intent = Intent(this, DetailActivity::class.java)
    val options = ActivityOptions.makeSceneTransitionAnimation(this, tvCryptocurrencyName, "cryptocurrency_name")
    intent.putExtra(EXTRA_STRING_CRYPTOCURRENCY_DETAILS, cryptocurrency)
    startActivity(intent, options.toBundle())
}

当按下项时要触发的方法设置为适配器中的接口:

代码语言:javascript
复制
interface OnItemClickListener {
    fun onItemClick(cryptocurrency: Cryptocurrency)
}

override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
    val cryptocurrency = cryptocurrenciesList[position]
    holder.populateUi(cryptocurrency)
    holder.itemView.setOnClickListener { onItemClickListener?.onItemClick(cryptocurrenciesList[position]) }
}

当我按下查看结果时,应用程序与消息一起崩溃。

代码语言:javascript
复制
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.gabriel.cryptocurrencies, PID: 4416
    java.lang.IllegalArgumentException: Shared element must not be null
        at android.app.ActivityOptions.makeSceneTransitionAnimation(ActivityOptions.java:694)
        at android.app.ActivityOptions.makeSceneTransitionAnimation(ActivityOptions.java:649)
        at com.example.gabriel.cryptocurrencies.ui.main.MainActivity.onItemClick(MainActivity.kt:50)
        at com.example.gabriel.cryptocurrencies.ui.main.MainAdapter$onBindViewHolder$1.onClick(MainAdapter.kt:36)
        at android.view.View.performClick(View.java:6261)
        at android.view.View$PerformClick.run(View.java:23752)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

通过其他的教程,这就是我所要做的。也许我试图从RecyclerView的布局访问字段的方式是错误的?

编辑

更新的但仍然失败的代码。现在,动画似乎会冻结,因为当我按后退按钮一次,它不会离开应用程序,只有当我按两次。此外,在编辑代码和部署更改时,应用程序将在尝试切换到details视图后加载细节视图。

MainActivity

代码语言:javascript
复制
override fun onItemClick(cryptocurrency: Cryptocurrency, field: View) {
    val intent = Intent(this, DetailActivity::class.java)
    intent.putExtra(EXTRA_CRYPTOCURRENCY_DETAILS, cryptocurrency)
    intent.putExtra(EXTRA_TRANSITION_NAME, cryptocurrency.id)

    val options = ActivityOptions.makeSceneTransitionAnimation(this, field, cryptocurrency.id)
    startActivity(intent, options.toBundle())
}

MainAdapter

代码语言:javascript
复制
val tvCryptocurrencyName = holder.itemView.tv_cryptocurrency_name

interface OnItemClickListener {
    fun onItemClick(cryptocurrency: Cryptocurrency, field: View)
}

holder.itemView.setOnClickListener { onItemClickListener?.onItemClick(cryptocurrenciesList[position], tvCryptocurrencyName) }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-08 13:45:09

您必须在RecyclerView的适配器的onBindViewHolder方法中为每个项设置唯一的转换名称。

就像这样:

代码语言:javascript
复制
ViewCompat.setTransitionName(holder.ivIcon, cryptocurrency.id.toString())

通过Intent发送Intent,在详细信息活动中获取该transitionName,然后将其设置为您的View

代码语言:javascript
复制
val iconTransitionName = intent.getStringExtra(EXTRA_TRANSITION_NAME)
ivIcon.transitionName = iconTransitionName

UPD:

AdapteronBindViewHolder方法中:

代码语言:javascript
复制
ViewCompat.setTransitionName(holder.itemView, cryptocurrenciesList[position].id)

onItemClick()

代码语言:javascript
复制
override fun onItemClick(cryptocurrency: Cryptocurrency, textView: TextView) {
    val transitionName = ViewCompat.getTransitionName(textView)
    val intent = Intent(this, DetailActivity::class.java)
    val options = ActivityOptions.makeSceneTransitionAnimation(this, textView, transitionName) // You should send exactly this instace of TextView, not by it's id
    intent.putExtra(EXTRA_STRING_CRYPTOCURRENCY_DETAILS, cryptocurrency)
    intent.putExtra(EXTRA_STRING_TRANSITION_NAME, cryptocurrency.id.toString())
    startActivity(intent, options.toBundle())
}

DetailActivityonCreate()

代码语言:javascript
复制
val transitionName = intent.getStringExtra(EXTRA_STRING_TRANSITION_NAME)
tv_cryptocurrency_detail_name.transitionName = transitionName

values-v21/styles.xml中添加:

代码语言:javascript
复制
<style name="MaterialAnimations" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowContentTransitions">true</item>
</style>

并将其添加到您的TextView中:

代码语言:javascript
复制
style="@style/MaterialAnimations"

寻找简单的例子:Github回购

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52703569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档