douling6469 2014-06-02 16:38
浏览 86
已采纳

如何在Android应用中实现“加载”指示器

Ok, so right now I have a ListView which is being populated by information via a PHP script. Right now, the list loads one at a time. By this, I mean the user can see when each listing is loaded (e.g. they see one item, one second later they see the second item, etc.) What I want to do is to WAIT until all the items are retrieved and then display them all at once. And while this is happening, to have some type of "loading" indicator (maybe a spinning circle type deal). Is there any way I can implement this? Here is my code:

public class MainActivity extends ActionBarActivity {

    ArrayList<Location> arrayOfLocations;
    LocationAdapter adapter;
    Button refresh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        // Construct the data source
        arrayOfLocations = new ArrayList<Location>();

        // Create the adapter to convert the array to views
        adapter = new LocationAdapter(this, arrayOfLocations);

        getData();

        // Attach the adapter to a ListView
        ListView listView = (ListView) findViewById(R.id.listView1);
        listView.setAdapter(adapter);
    }
}

So, my getData() method adds each Location into the adapter and then my Adapter class is what put the data into the ListView:

public class LocationAdapter extends ArrayAdapter<Location> {
    public LocationAdapter(Context context, ArrayList<Location> locations) {
        super(context, R.layout.item_location, locations);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Get the data item for this position
        Location location = getItem(position);
        // Check if an existing view is being reused, otherwise inflate the view
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(
                    R.layout.item_location, parent, false);
        }

        // Lookup view for data population
        TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
        TextView tvDetails = (TextView) convertView
                .findViewById(R.id.tvDetails);
        TextView tvDistance = (TextView) convertView
                .findViewById(R.id.tvDistance);
        TextView tvHours = (TextView) convertView.findViewById(R.id.tvHours);
        ImageView ivIcon = (ImageView) convertView.findViewById(R.id.imgIcon);

        // Populate the data into the template view using the data object
        tvName.setText(location.name);
        tvDetails.setText(location.details);
        tvDistance.setText(location.distance);
        tvHours.setText(location.hours);
        ivIcon.setImageBitmap(location.icon);
        // Return the completed view to render on screen
        return convertView;
    }
}

Also, I have code for a simple loading indicator:

public class MainActivity extends Activity {

    private ProgressDialog progress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progress = new ProgressDialog(this);
    }

    public void open(View view) {
        progress.setMessage("Loading...Please Wait");
        progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progress.setIndeterminate(true);
        progress.show();

        final int totalProgressTime = 100;

        final Thread t = new Thread() {

            @Override
            public void run() {

                int jumpTime = 0;
                while (jumpTime < totalProgressTime) {
                    try {
                        sleep(200);
                        jumpTime += 5;
                        progress.setProgress(jumpTime);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }

            }
        };
        t.start();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

So basically, what I am trying to do is figure out how to do this: 1. When the activity starts, display "loading" indicator 2. Load ALL items into ListView 3. When all items are listed, remove "loading" indicator and display ListView

Any ideas? Thanks.

  • 写回答

2条回答 默认 最新

  • duanfeng3879 2014-06-02 17:42
    关注

    To do this you need a class that extends AsyncTask. In this class in the method doInBackground you need to do all the "heavy" stuff. In your case populate your ListView. In case you want to show your progress you can call the publishProgress method at the end of each iteration. Finally in the method onPostExecute you can inform the user that the process finished. Here's a simple example

     public class ExampleAsync extends AsyncTask <Void, Integer, Void> {
    
         private ProgressDialog progressBar; //to show a little modal with a progress Bar
     private Context context;  //needed to create the progress bar
    
         public ExampleAsync(Context context){
               this.context = context;
         }
    
         //this is called BEFORE you start doing anything 
         @Override 
         protected void onPreExecute(){
             progressBar = new ProgressDialog(context);
             progressBar.setCancelable(false);
             progressBar.setMessage("I am starting to look for stuff");
             progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
             progressBar.setIndeterminate(true);
             progressBar.show();
         }
    
         //every time you call publishProgress this method is executed, in this case receives an Integer
         @Override
     protected void onProgressUpdate(Integer ... option){
             progressBar.setMessage("I have found :" + option[0]);      
    }  
    
         @Override
     protected void onPostExecute(Void unused){     
          progressBar.dismiss(); //hides the progress bar
              //do whatever you want now
    }
    
    
    
         //in here is where you execute your php script or whatever "heavy" stuff you need
         @Override
     protected Void doInBackground(Void... unused) {          
            for (int i = 0; i < someLimit; i++){
                 //do something
                 publishProgress(i); //to show the progress
            }
         } 
    
    
    
    
     }
    

    And in your main activity:

    //code
    new ExampleAsync(this).execute();
    

    Obviously this is a simple example. You can do lots of stuff in the onProgressUpdate method, and it's this method that you need to update the progress bar.

    Hope it helps

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器