我有一个导航抽屉,里面有很多选项
我们为每种材料维护单独的片段,每个片段都有网格视图,我们在其中填充该材料的缩略图。一旦用户点击缩略图,完整的材料将被下载(使用AsyncTask)。下载全部资料时,我在缩略图上显示进度条。
现在,我坚持一个假设进度条显示为20%的问题,我将片段切换到另一个片段,然后又回到原来的位置,下载进度条丢失了。
我找到了一种解决方案,使用意图服务和广播接收器来填充进度条,但是在这种情况下,每增加一个字节就会进行广播,这是一个好的实践吗?
发布于 2015-09-20 04:58:29
以前的答案不够好,我编了一个新的,看一看,效果很好。
代码由片段的基类、两个片段、网格元素数据保存模型和主UI线程组成。
基类:
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by Movsar Bekaev on 20/09/2015.
*/
public class GridFragment extends Fragment {
static ArrayList<xThumbnail> myInformation;
static Activity mActivity;
GAdapter adapter;
GridView grid;
enum fragment_names {FR1, FR2}
static fragment_names this_fragment_name;
public GridFragment() {
refresh();
}
protected void refresh() {
if (grid == null) {
grid = new GridView(mActivity);
grid.setLayoutParams(new GridView.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
grid.setBackgroundColor(Color.WHITE);
grid.setNumColumns(2);
grid.setColumnWidth(GridView.AUTO_FIT);
grid.setVerticalSpacing(5);
grid.setHorizontalSpacing(5);
grid.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
}
adapter = new GAdapter(mActivity, myInformation);
grid.setAdapter(adapter);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
refresh();
return grid;
}
public class GAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<xThumbnail> mInfo;
// Gets the context so it can be used later
public GAdapter(Context c, ArrayList<xThumbnail> info) {
mInfo = info;
mContext = c;
}
// Total number of things contained within the adapter
public int getCount() {
return mInfo.size();
}
public xThumbnail getItem(int position) {
return mInfo.get(position);
}
// Require for structure, not really used in my code. Can
// be used to get the id of an item in the adapter for
// manual control.
public long getItemId(int position) {
return position;
}
public View getView(final int position,
View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.thumbnail, null);
final TextView tv = (TextView) v.findViewById(R.id.tvClickMe);
final ProgressBar pb = (ProgressBar) v.findViewById(R.id.prgb_progress);
pb.setProgress(mInfo.get(position).getProgress());
tv.setText(mInfo.get(position).getProgress() + "");
mInfo.get(position).setProgressBar(pb);
mInfo.get(position).setTextView(tv);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOp(mInfo.get(position), position, this_fragment_name);
}
});
} else {
v = convertView;
}
return v;
}
}
private void runOp(final xThumbnail x, final int position, final fragment_names f_name) {
if (x.xt == null) {
x.xt = new Thread(new Runnable() {
@Override
public void run() {
for (int i = x.getProgress(); i <= 100; i++) {
// UNCOMMENT IF YOU WANT TO STOP THE PROCESS AFTER SWITCHING
// if ((f_name == this_fragment_name) && !mThread.isInterrupted()) {
final int progress = i;
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
x.setProgressBar(adapter.getItem(position).getProgressBar());
x.setTextView(adapter.getItem(position).getTextView());
x.setProgress(progress);
x.getProgressBar().setProgress(progress);
x.getTextView().setText(progress + "");
// ARBITRARY CHANGE OF MYINFORMATION
// JUST TO SHOW THAT IT WORKS
if (progress == 20) {
myInformation.get(3).setProgress(12);
refresh();
}
// **********************************
}
});
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
// } else {
// return;
// }
}
}
});
}
if (!x.xt.isAlive())
x.xt.start();
}
}的fr1.java:
public class fr1 extends GridFragment {
static ArrayList<xThumbnail> fr1Info;
public static fr1 newInstance(Activity act) {
mActivity = act;
return new fr1();
}
@Override
protected void refresh() {
if (fr1Info == null || fr1Info.size() == 0) {
fr1Info = new ArrayList<>();
for (int i = 0; i < 10; i++) {
xThumbnail x;
x = new xThumbnail();
fr1Info.add(x);
}
}
myInformation = fr1Info;
super.refresh();
}
}的fr2.java:
public class fr2 extends GridFragment {
static ArrayList<xThumbnail> fr2Info;
public static fr2 newInstance(Activity act) {
mActivity = act;
return new fr2();
}
@Override
protected void refresh() {
if (fr2Info == null || fr2Info.size() == 0) {
fr2Info = new ArrayList<>();
for (int i = 0; i < 10; i++) {
xThumbnail x;
x = new xThumbnail();
fr2Info.add(x);
}
}
myInformation = fr2Info;
super.refresh();
}
}xThumbnail.java (模型):
public class xThumbnail {
private int prgb_value = 0;
private ProgressBar pb;
private TextView tv;
public Thread xt;
public void setProgress(Integer i) {
prgb_value = i;
}
public Integer getProgress() {
return prgb_value;
}
public void setProgressBar(ProgressBar prb) {
pb = prb;
}
public ProgressBar getProgressBar() {
return pb;
}
public void setTextView(TextView tv) {
this.tv = tv;
}
public TextView getTextView() {
return tv;
}
}The MainActivity.java:
public class MainActivity extends AppCompatActivity {
Button btn_one, btn_two;
fr1 mFr1;
fr2 mFr2;
FragmentManager fm = getFragmentManager();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
mFr1 = (fr1) fm.findFragmentByTag("fr1");
mFr2 = (fr2) fm.findFragmentByTag("fr2");
final FrameLayout frameLayout = (FrameLayout)findViewById(R.id.frLayout);
btn_one.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GridFragment.this_fragment_name= GridFragment.fragment_names.FR1;
if (mFr1 == null) {
mFr1 = fr1.newInstance(MainActivity.this);
fm.beginTransaction().add(R.id.frLayout, mFr1, "fr1").commit();
} else {
fm.beginTransaction().detach(mFr1).commit();
fm.beginTransaction().attach(mFr1).commit();
}
}
});
btn_two.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GridFragment.this_fragment_name= GridFragment.fragment_names.FR2;
if (mFr2 == null) {
mFr2 = fr2.newInstance(MainActivity.this);
fm.beginTransaction().add(R.id.frLayout, mFr2, "fr2").commit();
} else{
fm.beginTransaction().detach(mFr2).commit();
fm.beginTransaction().attach(mFr2).commit();
}
}
});
}
}activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:id="@+id/btn_one"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:id="@+id/btn_two"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/prgb_uni"
android:layout_alignEnd="@+id/prgb_uni" />
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/prgb_uni"
android:layout_alignParentBottom="true"
android:layout_marginBottom="40dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:id="@+id/frLayout"></FrameLayout>
</RelativeLayout>thumbnail.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/prgb_progress" />
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="ClickMe!"
android:id="@+id/tvClickMe"
android:layout_gravity="center_horizontal"
android:textIsSelectable="false" />
</FrameLayout>它所做的:我们这里有一个基类,它使用视图的表示和填充进度条来操作。它有用于当前项(保存进度条值)的字段,每当我们在片段之间切换时,该字段被更新为相应的Fragment1或Fragment2值,这些片段具有静态字段来保存自己的数据,以便可以更改和使用。
使用Thread和一些其他代码的目的只是为了显示它的工作原理和更好的理解。
我希望这会有所帮助。
PoC - mA :)
发布于 2015-09-19 13:16:09
作为一个抽象的蓝图,您可以添加一个下载Service到您的应用程序,让它下载您的材料。
为了与该服务进行通信,您可能希望将其声明为可绑定服务,以便每当用户切换到该片段时,您的活动就可以绑定到该服务,并查看正在发生的事情。
使用这种方式,您可以向用户报告下载进度,并且不再需要发送广播。
https://stackoverflow.com/questions/32668285
复制相似问题