如何使用 contentprovider 用数据库列的总和填充单个文本视图

发布于 2024-12-13 10:49:09 字数 420 浏览 7 评论 0 原文

这是什么问题啊! 更清楚地描述它: 我正在使用片段,我的目标是有一个 TextView 显示数据库表列的总和。每次以不同方式更新表(删除、插入、更新)时,都应更新此总和。 如果没有 contentprovider,我会在 DBHelper 类中编写一个返回值的方法。但问题开始了。以编程方式更新文本视图在片段中确实很困难(甚至不可能)。因此,我喜欢使用 contentprovider,因为它总是通知我的列表视图有关更改的信息,而无需我进行任何额外的工作。在这种情况下(contentprovider)我(恕我直言)将加载器方法 onCreateLoader() 和 onLoadFinished() 与游标加载器和 uri 一起使用。但它们都返回一个光标对象,而我无法将其附加到这个单个文本视图上。 在研究列表视图和内容提供者这么多天之后,我的想法可能太“宏大”,因此我无法看到简单文本视图的简单解决方案。如果有的话...

What a question!
To describe it more clearly:
I'm using fragments and my target is to have a TextView that shows the total sum of a database table column. This total sum should be updated everytime the table is updated in different ways (delete, insert, update).
Without the contentprovider I would write a method in my DBHelper class that would return the value. But the the problem begins.It's really difficult (till impossible) in fragments to update the textview programmatically. Therefore I like to use the contentprovider because it always informs my listviews about changes without any additional work from my side. In this case (contentprovider) I have (imho) to use the loader methods onCreateLoader() and onLoadFinished() with a cursorloader and a uri. But they all are returning a cursor object and that's nothing I can attach on this single textview.
After all the days working on listviews and contentproviders my thinking is maybe too "bigpictured" so that I'm not able to see a simple solution for a simple textview. If there is any...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞美少年 2024-12-20 10:49:09

我至少找到了一种解决方法。如果有人知道更好的解决方案,我将不胜感激。

为了使用 Loader,您必须重写 3 个方法:

  • onCreateLoader(int id, Bundle arg1)
  • onLoadFinished(Loader loader, Cursorcursor) 和
  • onLoaderReset(Loader arg0)

因此,假设我们有一个 TextView 电视,应该通过 ContentProvider 进行更新。

onCreateLoader() 中:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
        String select = "where _id="+id; //id is definied earlier in this program
        loader = new CursorLoader(getActivity(),
                MaterialContentProvider.READ_SINGLE_MATSTAMM_URI, null, select, null, null);
    }
    return loader;
}

MaterialContentProvider.READ_SINGLE_MATSTAMM_URI 是我的 URI,它显示要使用的 ContentProvider wich 数据库表以及如何使用。在这种情况下,我将得到一个结果。
我们将通过 onLoadFinished() 异步获得此信息,这是我的解决方法:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {

     final TextView tv = (TextView) View.findViewById(R.id.mytextview);
     tv.setText(cursor.getString(cursor.getColumnIndex("myColumn")));
}

从现在开始,每次 onCreateLoader() 中 uri 所针对的表中的内容发生变化时,您的 TextView tv 都会更新。 “技巧”是不要像平常那样放弃光标(使用类似“adapter.swap(cursor)”的东西),因为那里没有适配器。为了获得一列的总和,您必须使用光标获取此特殊列的所有行(这意味着您有不同的 uri)。

I found one, at least, workaround. Would appreciate if somebody knows a better solution.

In order to use Loader you have to override 3 methods:

  • onCreateLoader(int id, Bundle arg1)
  • onLoadFinished(Loader loader, Cursor cursor) and
  • onLoaderReset(Loader arg0)

So let's say we have a single TextView tv that should be updated via ContentProvider.

in onCreateLoader():

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
        String select = "where _id="+id; //id is definied earlier in this program
        loader = new CursorLoader(getActivity(),
                MaterialContentProvider.READ_SINGLE_MATSTAMM_URI, null, select, null, null);
    }
    return loader;
}

MaterialContentProvider.READ_SINGLE_MATSTAMM_URI is my URI that shows the ContentProvider wich db table to use and how. In this case I'll get a single result.
This we will get asynchroniosly via onLoadFinished() and here comes my workaround:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {

     final TextView tv = (TextView) View.findViewById(R.id.mytextview);
     tv.setText(cursor.getString(cursor.getColumnIndex("myColumn")));
}

From now on your TextView tv will be updated everytime the content changes in the table that is targeted by the uri in onCreateLoader(). The "trick" is to not give away the cursor like you usually do (with something like "adapter.swap(cursor)") because there is nothing with an adapter outthere. In order to get a total sum of a column you have to get all the rows of this special column with the cursor (wich means that you have a different uri).

醉城メ夜风 2024-12-20 10:49:09

我使用了如图所示的方法 此处
基本上,您必须使用 Handler 将字符串从 Cursor 发送到 UI。
您还需要前进到第一个 Cursor 位置:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    if (cursor.moveToFirst()) {
        final String text =  cursor.getString(cursor.getColumnIndex(""myColumn));
        final TextView tv = (TextView) View.findViewById(R.id.mytextview);
        handler.post(new Runnable() {
            public void run() {
                tv.setText(text);
            }
        });
    }
}

并且不要忘记,当 Cursor 重置时,您必须清除 UI。

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    final TextView tv = (TextView) View.findViewById(R.id.mytextview);
    handler.post(new Runnable() {
        public void run() {
            tv.setText("");
        }
    });
}

I used the approach as shown here.
Basically you have to us a Handler to post the string from the Cursor to the UI.
And you alo need to advance to the first Cursor-position:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    if (cursor.moveToFirst()) {
        final String text =  cursor.getString(cursor.getColumnIndex(""myColumn));
        final TextView tv = (TextView) View.findViewById(R.id.mytextview);
        handler.post(new Runnable() {
            public void run() {
                tv.setText(text);
            }
        });
    }
}

And not to forget that you have to clear the UI when the Cursor is reset.

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    final TextView tv = (TextView) View.findViewById(R.id.mytextview);
    handler.post(new Runnable() {
        public void run() {
            tv.setText("");
        }
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文