我有一个非常标准RecyclerView的垂直LinearLayoutManager.我一直在顶部插入新物品,我正在打电话notifyItemInserted(0).
我希望列表保持滚动到顶部 ; 始终显示第0个位置.
从我的要求来看,LayoutManager根据项目数量的不同表现.
虽然所有项目都适合屏幕,但它的外观和行为与我预期的一样:新项目始终显示在顶部,并将所有项目都移到它下面.
但是,一旦没有.项目超出RecyclerView的范围,新项目将添加到当前可见项目之上,但可见项目仍保留在视图中.用户必须滚动才能看到最新的项目.
对于许多应用程序来说,这种行为是完全可以理解的,但不适用于"实时馈送",其中看到最近的事情比使用自动滚动"不分散"用户更重要.
我知道这个问题几乎与在RecyclerView的顶部添加新项目相同 ......但是所有建议的答案都只是解决方法(大多数都非常好,不可否认).
我正在寻找一种方法来实际改变这种行为.我希望LayoutManager的行为完全相同,无论项目数量多少.我希望它总是移动所有项目(就像它为前几个添加项目所做的那样),而不是停止在某些时候移动项目,并通过平滑滚动列表到顶部进行补偿.
基本上,不smoothScrollToPosition,不RecyclerView.SmoothScroller.子类化LinearLayoutManager很好.我已经挖掘了它的代码,但到目前为止没有任何运气,所以我决定询问以防有人已经处理过这个问题.谢谢你的任何想法!
编辑:澄清为什么我从相关问题中驳回答案:主要是我关注动画的平滑性.
请注意,在第一个GIF中,ItemAnimator在添加新项目的同时移动其他项目,淡入和移动动画都具有相同的持续时间.但是当我通过平滑滚动"移动"项目时,我无法轻易控制滚动的速度.即使使用默认ItemAnimator持续时间,这看起来也不太好,但在我的特定情况下,我甚至需要减慢ItemAnimator持续时间,这会使情况变得更糟:
2.2.3到2.3.3与之前相关的迁移指南指出,我所需要的只是
- 确保您使用的是Android Gradle 2.2插件或更新版本
- 从构建脚本中删除android-apt插件
- 将所有apt,androidTestApt和testApt依赖项更改为新格式
这应该是成功构建项目所需的全部内容.但它没有建立.
Gradle构建完成了101个错误和23个警告(12秒481ms)
所有错误都遵循相同的模式:
- C:\用户\ FooAdapter.java
- 错误:包
com.example.app.databinding不存在- 错误:找不到符号类
ItemFooBinding
在构建控制台中可以找到一条有趣的消息:
警告:任何处理器都无法识别以下选项:'[android.databinding.minApi,android.databinding.enableDebugLogs,android.databinding.sdkDir,android.databinding.bindingBuildFolder,android.databinding.enableForTests,android.databinding.modulePackage, android.databinding.generationalFileOutDir,android.databinding.xmlOutDir,android.databinding.artifactType,android.databinding.printEncodedErrors,android.databinding.isTestVariant]'
我想指出......
以下差异显示了我如何修改我的gradle文件:
build.gradle DiffChecker链接app/build.gradle DiffChecker链接另外,作为一个快速概述,这里是项目使用的一些"更有趣"的插件和库的列表:
有没有人知道可能是什么问题?任何帮助或想法将非常值得赞赏!
android android-build android-studio android-gradle-plugin android-databinding
这就是我所拥有的 - 一个ListBox,其ItemsSource设置为ObservableCollection<T>
- 其中T是我的自定义类,表示一个文件,只包含2个DependencyProperties:Filename和ThumbnailPath. - 列表框还定义了自定义DataTemplate,以便在其下很好地显示图像和文件名.
列表框的目的是显示当前文件夹(在TreeView中选择)中的视频文件,缩略图(异步生成;不是此问题的一部分).
因此,当我更改TreeView中的文件夹时,ObservableCollection将被清除并再次填充,这将自动反映在ListBox项目中.
问题在于:UI变得无响应,更新需要几秒钟.同样,缩略图在这里没有意义(我尝试禁用它们). 我认为花费最多时间的是构建我自定义类的50-100个实例及其可视化表示 - 它必须为每个实例初始化一个Image对象.但这只是我的猜测 - 你能否确认或排除这种可能性?
我开始认为ObservableCollection可能不是这里的方式,因为根据我的阅读和我尝试的内容,没有办法异步添加项目,至少如果这些项是DependencyObjects.我尝试使用BackgroundWorker创建我的类实例并将它们添加到ProgressChanged事件处理程序中的集合中,但它会抛出异常(某些线程与dependencyobjects问题).
有什么东西我不见了吗?或者通过简单地抛弃ObservableCollection并编写一个好的旧异步for循环来添加项目,我会更好吗?
假设您有一个Collection<B>,并且您即将删除一个项目.实例B是从一个实例A引用的,并引用了一个实例C,如第一张图所示:
图A http://i43.tinypic.com/240wuqh.jpg
现在,由于存在指向B的引用,因此毫无疑问该对象被"删除"或被垃圾收集.它只是从集合中删除,就像这样,对吗?
图B http://i41.tinypic.com/4uxnp3.png
现在,让我们使用Collection<A>与之前相同的引用层次结构,让我们删除A的实例.
图C http://i44.tinypic.com/1zd93dt.png
如果没有其他引用A,不仅它从集合中删除,它被标记为垃圾.我对吗?并且怎么样B和C?它们是否也成为垃圾,除非B引用一个实例,否则没有其他引用C?
这是我所面临的简化.我想A从集合中删除一个实例,我想确保B并C继续使用它.在A我不再收集的地方,所有仍然活着的"孩子"对我来说都是记忆泄漏.
当我看到我制作的这些照片时,这个问题似乎太愚蠢了.但我的情况有点不那么微不足道.它看起来像这样:
图4 http://i41.tinypic.com/2ymhlq0.png
A ModelA Model有一个B Model实例集合(在Model和ViewModel层中B都是一种子类A)B Model"知道它的父亲" - 引用其父"模型"实例我有这些A ViewModel实例的集合.当我删除一个时,我需要其他所有内容.如果所涉及的任何实例没有其他"外部参考"(基本上,没有其他箭头指向图片外部),被移除的"ViewModel"实例是否会将所有孩子带走?如果是这样,是否有任何"陷阱"可以使这种简化误导?如果我完全错了,为什么?:)
感谢您阅读这篇文章!
WPF的MVVM设计模式中Model,View和ViewModel对象的基本定义是什么?他们的责任是什么,他们每个人应该和不应该做什么?
我的大多数测试方法首先尝试两个或三个简单的操作,这应该引发异常,然后开始真正的工作.在Java中,我会这样写:
@Test
public void TestSomething() {
try {
testedClass.testedMethod(null);
fail();
catch (IllegalArgumentException ex) {
// OK
}
// and now let's get to the point ...
// ...
}
Run Code Online (Sandbox Code Playgroud)
我想在C#中坚持这种习惯,但似乎没有办法强迫测试方法失败.我已经看了一会儿,但没有运气.我错过了什么吗?
PS:我知道测试这些情况的正确方法是:
[TestMethod]
[ExpectedException(ArgumentNullException)]
public void TestSomethingWithNull() {
testedClass.TestedMethod(null);
}
[TestMethod]
public void TestSomething() {
// now the non-trivial stuff...
}
Run Code Online (Sandbox Code Playgroud)
......但是,我不喜欢这个.当我有,比方说,我的测试类中的6个测试方法,并且每个测试应该从覆盖三个琐碎的,一行情况开始,这应该引发异常,使用这种方法将我的6个测试变成18个.应用程序,这确实污染了我的测试资源管理器,并使结果更难以扫描.
并且假设我想测试一个方法,该方法的职责是验证某个类的给定实例的每个属性,如果任何值不正确则引发ValidationException.这可以通过一个TestValidation()测试轻松处理,但是使用这种方法,将其转换为:
想象一下,你有20个属性...... :)
当然,如果这是唯一的方法,我会咬人.
我创建了一个包含带有setter的Long属性的类.当尝试使用setter将值设置为某个随机数时,Idea告诉我实际的参数int不能通过方法调用转换转换为Long.
这是我的班级:
public myClass() {
private Long id;
public Long getId() {
return this.id;
}
public Long setId(Long id) {
if(this.id == null)
this.id = id;
else throw new InvalidOperationException("Can't set more than once.");
}
}
Run Code Online (Sandbox Code Playgroud)
而在其他地方,我只是想:
MyClass myInstance = new myClass();
myInstance.setId(15);
Run Code Online (Sandbox Code Playgroud)
构建错误暗示我尝试这样的技巧:
long newID = 17;
myInstance.setId(newID);
Run Code Online (Sandbox Code Playgroud)
...... 有效.唯一奇怪的是,我在NetBeans中打开了一个不同的项目,并且在相同的情况下没有编译错误(并且排除任何"外部"影响或不需要的交互是非常安全的,这一切都像我的代码片段一样简单) .
这可能是编译器设置的事吗?我现在想了解一下发生了什么,为什么我不能使用它myInstance.setId(15)
.net ×3
c# ×3
android ×2
wpf ×2
data-binding ×1
java ×1
memory-leaks ×1
mvvm ×1
types ×1
unit-testing ×1