我有一个类似聊天的活动,我使用带有PagedListAdaper的RecyclerView来加载一堆消息.我正在使用PositionalDataSource来加载数据.加载它的自我工作正常但是当我发送消息时,我使我的数据源无效并且列表被重新制作.我的问题是,当它这样做时它会闪烁:

我尝试添加setHasStableIds(true)并重写getItemId,它可以在一个简单的适配器上工作,但它似乎在这里不起作用.我似乎也无法将项添加到getCurrentList(),因为它不受支持.此外,我没有使用数据库,只是向服务器发出请求.
所以我的问题是,除了使数据源失效之外,还有更好的方法吗?有没有办法阻止列表在发送消息时闪烁?或者这个图书馆不适合我的聊天活动?
编辑:
我的差异回调
private val DIFF_CALLBACK: DiffCallback<MessageModel> = object : DiffCallback<MessageModel>() {
override fun areItemsTheSame(@NonNull oldMessage: MessageModel, @NonNull newMessage: MessageModel) =
oldMessage.id == newMessage.id
override fun areContentsTheSame(@NonNull oldMessage: MessageModel, @NonNull newMessage: MessageModel) =
oldMessage.equals(newMessage)
}
Run Code Online (Sandbox Code Playgroud)
Edit2我修复了它:
所以我设法通过使用PagedListAdapterHelper并在加载项目后设置它的列表来修复它:
private var mHelper: PagedListAdapterHelper<MessageModel>? = null
init {
mHelper = PagedListAdapterHelper(this, DIFF_CALLBACK)
setHasStableIds(true)
}
fun setList(pagedList: PagedList<MessageModel>) {
pagedList.addWeakCallback(pagedList.snapshot(), object:PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {
}
override fun onInserted(position: Int, count: Int) {
mHelper?.setList(pagedList) …Run Code Online (Sandbox Code Playgroud) 对不起,如果怀疑太概念化,我有点缺乏经验......
我通过改造从URL获取JSON数据,我还想将这些数据存储在我的SQLite数据库中.要创建此数据库,我将使用新的Room ORM映射.
我使用Android Studio插件GsonFormat提取网络POJO类,并在下面生成食谱,成分和步骤类.并生成一些Room Entity类(更多下面)
如您所见,两组类几乎相同,带来了大量重复的代码.但我也觉得混合使用这两组课程并不好.并且Room禁止实体对象互相引用,所以如果我想使用第一组类,它会更复杂......
我怀疑这些案件一般是如何处理的?
--- Pojo - Gson可以理解:
public class Recipes {
private int id;
private String name;
private int servings;
private String image;
private List<Ingredients> ingredients;
private List<Steps> steps;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getServings() {
return servings;
}
public void setServings(int servings) {
this.servings = …Run Code Online (Sandbox Code Playgroud) rest android retrofit2 android-room android-architecture-components
我正在Android项目中使用Room + LiveData.在Google蓝图之后,我实现了应用程序的数据层.
这就是我的Dao的样子:
@Query("SELECT * FROM events WHERE id=:arg0")
fun loadSingle(id: String): LiveData<Event>
Run Code Online (Sandbox Code Playgroud)
我从我的EventRepository调用它:
fun loadSingle(eventId: String): LiveData<RequestReader<Event>> {
return object: NetworkManager<Event, Event>(appExecutors!!) {
override fun loadLocal(): LiveData<Event> {
val item = eventLocal!!.loadSingle("Title 1")
Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::loadLocal=$item")
return item
}
override fun isUpdateForced(data: Event?): Boolean {
Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::isUpdateForced")
return data == null || requestTimeout.isAllowed(UNDEFINED_KEY.toString())
}
override fun makeRequest(): LiveData<ApiResponse<Event>> {
Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::makeRequest")
return Database.createService(EventRemote::class.java).load(eventId)
}
override fun onSuccess(item: Event) {
eventLocal?.save(item)
}
override fun onFail() {
Crashlytics.log(Log.VERBOSE, …Run Code Online (Sandbox Code Playgroud) android android-room android-livedata android-architecture-components
我想在我的应用程序中使用Google架构组件,但在将android Studio更新为3.1.1时,我将android.arch.lifecycle:extensions:1.1.1依赖项添加到app.gradle文件中,它将显示Failed to resolve: support-fragment
我的gradle版本为4.4
这是app gardle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "ir.apptori.myapplication"
minSdkVersion 17
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation "android.arch.lifecycle:extensions:1.1.1"
}
Run Code Online (Sandbox Code Playgroud)
请指导我如何解决它,谢谢
android android-gradle-plugin android-architecture-components
我已经使用Android体系结构中的ViewModel已有一段时间了,并且恪守从不将ViewModel暴露于上下文/视图(Android Framework / UI)。但是,最近我遇到了一个有趣的问题。
制作计时器应用程序时,启动计时器时,将在运行计时器的后台运行服务。这样,当应用程序关闭时,计时器仍在通知栏中的前台运行,直到所有计时器都停止。但是,这意味着我所有的Timer对象和状态都包含在此服务中。我的UI需要在每个刻度上更新,但模型不一定需要更新。ViewModel如何适应这种情况?
活动是否应该每次都接收LocalBroadcasts并通知ViewModel?是否应该从Service-> Activity-> VM中读取UI状态?看起来服务似乎是ViewModel,但这似乎并不高效。
android mvvm android-service android-architecture-components
我无法理解这些注释之间的区别。在我的用例中,我想在表之间创建一对多关系。并找到了两个选项:一个是@ForeignKey,另一个是@Relation
我还发现,如果我更新该行(例如使用 OnCoflictStrategy.Replace),我将丢失该行的外键,这是真的吗?
Android 的导航组件能否用于在 BottomSheet 内导航(即在单个底部工作表中替换/添加片段)?
我知道如何BottomSheetDialogFragment使用<dialog>导航图中的标签启动一个。例如,下面的代码nav_graph.xml允许用户从一个BottomSheetDialogFragment(fragmentOne)导航到另一个BottomSheetDialogFragment(fragmentTwo)。FragmentTwo 作为第二个BottomSheet 打开,位于FragmentOne 的BottomSheet 之上。
但是,如果我想让 fragmentTwo 替换同一个 BottomSheet 中的 fragmentOne 怎么办?我将如何使用导航图完成此操作?
<navigation android:id="@+id/nav_graph"
app:startDestination="@id/fragmentOne">
<dialog android:id="@+id/fragmentOne"
android:name="com.example.navcomponentapp.FragmentOne"
android:label="fragment_fragment_one"
tools:layout="@layout/fragment_fragment_one">
<action android:id="@+id/action_fragmentOne_to_fragmentTwo2"
app:destination="@id/fragmentTwo"/>
</dialog>
<dialog android:id="@+id/fragmentTwo"
android:name="com.example.navcomponentapp.FragmentTwo"
android:label="fragment_fragment_two"
tools:layout="@layout/fragment_fragment_two"/>
</navigation>
Run Code Online (Sandbox Code Playgroud)
演示(这不是我想要的。我不想在另一个bottomSheet上打开一个bottomSheet

android android-navigation android-architecture-components android-jetpack android-navigation-graph
我已经成功地将底部导航与最新的 android 架构导航组件集成在一起。以下是我的完整代码。
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="in.zedone.bottomsample.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_saloons"
android:name="in.zedone.bottomsample.ui.saloons.SaloonsFragment"
android:label="@string/title_saloon"
tools:layout="@layout/fragment_saloons" />
<fragment
android:id="@+id/navigation_offers"
android:name="in.zedone.bottomsample.ui.offers.OffersFragment"
android:label="@string/title_offer"
tools:layout="@layout/fragment_offers" />
<fragment
android:id="@+id/navigation_account"
android:name="in.zedone.bottomsample.ui.account.AccountFragment"
android:label="@string/title_account"
tools:layout="@layout/fragment_account" />
</navigation>
Run Code Online (Sandbox Code Playgroud)
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:labelVisibilityMode="labeled"
app:itemTextAppearanceActive="@style/BottomNavigationView.Active"
app:itemTextAppearanceInactive="@style/BottomNavigationView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
Run Code Online (Sandbox Code Playgroud)
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations. …Run Code Online (Sandbox Code Playgroud) navigation android bottomnavigationview android-architecture-components
在我们的用户需求中,我们有这样的流程。
我搜索了以下内容:
https://developer.android.com/guide/navigation/navigation-principles
但没有什么可以帮助...
我做了什么?
目前我拆分了 2 个图并在 Graph2 中添加了重复的片段 C。此外,我以编程方式将图开始目标更改为图 1 中的片段 C,只有我从图 2 中单击。这是一个丑陋的解决方案但我不知道如何解决这个问题。
我的问题是:有什么办法可以做到而不是制作重复的目的地并更改起始目的地?
图一:
<include app:graph="@navigation/graph2" />
<dialog
android:id="@+id/fragmentA"
android:label="Fragment A"
tools:layout="@layout/fragmentA"/>
<dialog
android:id="@+id/fragmentB"
android:label="Fragment B"
tools:layout="@layout/fragmentB">
<action
android:id="@+id/NavigateToGraph2"
app:destination="@id/graph2">
</dialog>
<dialog
android:id="@+id/fragmentC"
android:label="Fragment C"
tools:layout="@layout/fragmentC"/>
<dialog
android:id="@+id/fragmentD"
android:label="Fragment D"
tools:layout="@layout/fragmentD"/>
<dialog
android:id="@+id/fragmentE"
android:label="Fragment E"
tools:layout="@layout/fragmentE"/>
Run Code Online (Sandbox Code Playgroud)
图2
<dialog
android:id="@+id/fragmentF"
android:label="Fragment F"
tools:layout="@layout/fragmentF"/>
<dialog
android:id="@+id/fragmentG"
android:label="Fragment G"
tools:layout="@layout/fragmentG"/>
<dialog
android:id="@+id/fragmentC"
android:label="Fragment C"
tools:layout="@layout/fragmentC"/>
Run Code Online (Sandbox Code Playgroud) android android-navigation android-architecture-components android-architecture-navigation
我的导航图有一个auth包含 LoginFragment 和 SignUpFragment 的子图:
<navigation
android:id="@+id/auth"
app:startDestination="@id/loginFragment">
<fragment
android:id="@+id/signUpFragment"
[...]
<fragment
android:id="@+id/loginFragment"
[...]
</fragment>
[...]
</navigation>
Run Code Online (Sandbox Code Playgroud)
我想检查这两个目的地中的任何一个当前是否位于返回堆栈上。但不要单独检查每个目的地,如下所示:
val currentDestId = navController.currentDestination?.id
if (currentDestId != R.id.loginFragment && currentDestId != R.id.signUpFragment) {
navController.navigate(
NavGraphDirections.actionGlobalLogin()
)
}
Run Code Online (Sandbox Code Playgroud)
我认为只检查身份验证图当前是否位于返回堆栈上会更干净。
我目前的方法如下:
val authBackStack = try {
navController.getBackStackEntry(R.id.auth)
} catch (t: Throwable) {
null
}
if (authBackStack == null) {
navController.navigate(
NavGraphDirections.actionGlobalLogin()
)
}
Run Code Online (Sandbox Code Playgroud)
这里的想法是,如果传递的目标(或本例中的图形)当前不在返回堆栈上,则getBackStackEntry抛出异常。IllegalStateException我们使用此异常作为指示器来查明我们的图形当前是否位于返回堆栈上。
这是一种有效的方法还是在某些情况下会失败?或者也许有更好的方法来检查返回堆栈是否包含某个子图的目的地?
navigation android android-architecture-components android-architecture-navigation
android ×10
android-architecture-components ×10
android-room ×3
android-architecture-navigation ×2
navigation ×2
mvvm ×1
rest ×1
retrofit2 ×1