小编Bri*_*uis的帖子

将项添加到ListView,保持滚动位置而不看滚动跳转

我正在构建类似于Google Hangouts聊天界面的界面.新消息将添加到列表底部.向上滚动到列表顶部将触发先前消息历史记录的加载.当历史从网络进入时,这些消息将添加到列表的顶部,并且不应从触发负载时用户已停止的位置触发任何类型的滚动.换句话说,列表顶部显示"加载指示符":

在此输入图像描述

然后将其替换为任何已加载的历史记录.

在此输入图像描述

我完成了所有这些工作......除了一件我不得不诉诸于反思的事情.当向连接到ListView的适配器添加项目时,有很多问题和答案涉及仅保存和恢复滚动位置.我的问题是当我做类似以下的事情时(简化但应该是不言自明的):

public void addNewItems(List<Item> items) {
    final int positionToSave = listView.getFirstVisiblePosition();
    adapter.addAll(items);
    listView.post(new Runnable() {

        @Override
        public void run() {
            listView.setSelection(positionToSave);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

然后用户将看到的是快速闪烁到ListView的顶部,然后快速闪回到正确的位置.这个问题很明显,并且被很多人发现:setSelection()直到之后notifyDataSetChanged()重新开始并且不重要ListView.所以我们必须要有post()机会画画.但那看起来很糟糕.

我通过使用反射来"修复"它.我讨厌它.在其核心,就是我要完成的任务是重置的第一位置ListView,而无需通过抽奖周期的rigamarole下去,直到后,我给自己定的位置.要做到这一点,ListView有一个有用的领域:mFirstPosition.通过gawd,这正是我需要调整的!不幸的是,它是包私有的.还不幸的是,似乎没有任何方式以编程方式设置它或以任何不涉及无效循环的方式影响它...产生丑陋的行为.

因此,反映失败的后备:

try {
    Field field = AdapterView.class.getDeclaredField("mFirstPosition");
    field.setAccessible(true);
    field.setInt(listView, positionToSave);
}
catch (Exception e) { // CATCH ALL THE EXCEPTIONS </meme>
    e.printStackTrace();
    listView.post(new Runnable() {

        @Override
            public void run() {
                listView.setSelection(positionToSave);
            }
        }); …
Run Code Online (Sandbox Code Playgroud)

android android-listview

26
推荐指数
1
解决办法
9686
查看次数

@Produces 之后的 @Injects?

我正在尝试通过 Dagger 2 学习 DI 并将其应用到我们的产品中。注释的应用程序级别的东西@Singleton非常简单(例如SharedPreferences)。在考虑我们的架构时,有几个本质上是异步的依赖项,我想象它们的范围@ForSession

  • 我们的身份验证令牌/帐户信息,从 Android 获取AccountManager。在现有有效会话的情况下可以是同步的。如果没有现有会话,并且AccountManager必须显示完整的登录流程,则可能是异步的。
  • 一旦我们有了有效的会话令牌和会话信息:
    • 提供一个Endpoint来满足依赖关系,以便我们的网络层知道在哪里可以找到 API。
    • 从网络 API 获取我们的“用户”信息。
    • 从网络 API(或本地缓存)中提取额外的支持信息。
    • 从网络 API(或本地缓存)中提取本地化的后端字符串。
    • 让依赖于绑定的组件运行起来ServiceService仅当绑定完成 时才异步提供该组件。

表示层应在收到这些项目的集合后进行门控。除了某种“正在加载”显示之外,如果没有上述任何一项,它就无能为力。

感觉这些依赖项适合 和 的用@ProducerModule@Produces。我觉得我可以@Produces ListenableFuture<>为每个依赖项提供方法,也许可以使用 aSettableFuture<>作为实现。执行任何需要的工作,呼唤set()未来,依赖性得到满足。

我感到不安的地方是《制作人指南》中的这句话。

正如上面的例子,生产者模块可以与普通模块无缝使用,但受到提供类型不能依赖于生产类型的限制。

对于“所有可用的东西的门演示”,我可以设想一个复合对象,可以@Inject通过打开T期货来获得。但这合法吗?

这是我最接近的,但它显式调用复合材料的构造函数,而不是注入它。有没有办法做到这一点清洁?

@ProducerModule
public class SessionModule {
@Produces
@ForSession
static ListenableFuture<User> produceSignedInUser(SessionManager sessionManager) {
    return sessionManager.getSignedInUserFuture();
}

@Produces
@ForSession …
Run Code Online (Sandbox Code Playgroud)

android dagger-2

5
推荐指数
1
解决办法
952
查看次数

标签 统计

android ×2

android-listview ×1

dagger-2 ×1