我有一个列表视图,每个列表项都有一个进度条。我想以这种方式在asynktask中控制进度条:在onPreExecute()进度条设置为可见,在onPostExecute()中进度条设置为消失。我已尝试使用以下代码,但有时这种方式无法正常工作且进度条始终可见:
private class sendMsg extends AsyncTask<String, String, String>{
String mess;
int ind;
@Override
protected void onPreExecute(){
ind=lv.getLastVisiblePosition();
addItems(mess, false,false,nick,null); //here I add the item to listview
}
@Override
protected String doInBackground(String... arg0) {.....}
@Override
protected void onPostExecute(String temp){
if(temp.equals("SUCCESS")) {
View v = lv.getChildAt(ind+1);
ProgressBar pbb = (ProgressBar) v.findViewById(R.id.messric);
pbb.setVisibility(View.GONE); }
}
listitem.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
>
<LinearLayout
android:id="@+id/bollavera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical"
android:layout_margin="10dp"
>
<TextView
android:id="@+id/comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_margin="5dip"
android:paddingLeft="10dip"
android:textColor="@android:color/primary_text_light"
android:textSize="18dp" />
<ProgressBar
android:id="@+id/messric"
style="?android:attr/progressBarStyleSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
此代码的另一个问题是:如果尝试从适配器使进度条可见,当有其他项目时,它们之前的项目再次有一个进度条,如果我旋转屏幕。我无法在onExreExecute()方法中看到进度条,因为我不知道该项目是否只是可见因为我之前添加了第1项。
答案 0 :(得分:2)
你应该制作你的自定义适配器(你有一个,对吧?)有两个类型的项目:一个用于何时应该显示进度条,一个用于什么时候不应该&#39;吨。我对this related question的回答可能会帮助您入门。
理论上,您可以在每个适配器项目上附加AsyncTask
。我从来没有对AsyncTask
进行过基准测试,但我猜你是否会因此而遇到性能问题。你可能最好开始一个工作线程,或者可能是一些处理这些项目然后报告的工作线程。拥有自定义HandlerThread
的{{1}}可能是实现这一目标的最简单方法。我在this question中对处理程序,处理程序线程和loopers之间的关系写了一个非常基本的解释,你可能会在SO上找到更多的搜索。
<强>更新强>
你正在研究两个不同的东西,现在正在捣乱它们:一个是业务逻辑,一个是可视化。您的适配器仅负责将数据转换为该数据的可视化表示(即显示或不显示进度条)。对该数据的操作应该发生在其他地方(例如,作为&#34;任务完成的结果&#34;工作线程发送给UI线程上的处理程序的消息)。例如,处理程序可以在相应的数据项上设置一个标志,并在数据结构上调用Handler
。
如果我是你,请按照以下方式进行:
我猜你现在正在使用一个简单的数组作为你的数据结构。我将其更改为我自己的结构并使其实现ContentObservable
。这可能最终成为数组或notifyChange
。
在UI线程上设置处理程序。
设置一个或多个处理与服务器进行网络通信的工作线程。每个人都应该有一个接受任务的队列,然后逐个运行。每次完成后,它都会在UI线程上向处理程序发送一条消息,类似于&#34;嘿,我完成了消息#123的工作,服务器说它是成功的&#34;。 (然后它继续从队列中执行下一个任务。)
您的处理程序转到您的数据结构,告诉它&#34;消息#123已由服务器&#34;确认。数据结构自身更新(例如,通过在与消息#123对应的任何项目上设置标志),然后在其自身上调用List
。
您自己的适配器必须在数据结构上注册为观察者。当它收到更改通知(来自您的数据结构)时,它将依次调用notifyDatasetChanged
强制视图更新。如果您已正确实施notifyChange
和getView
,则会自动使进度条可见或隐藏。