Показати ProgressDialog Android


78

У мене є EditText, який бере у користувача рядок та кнопку пошуку. Після натискання кнопки searchButton здійснює пошук у файлі XML і відображає його в ListView.

Я можу взяти введення від користувача, здійснити пошук у файлі XML і також відобразити значення пошуку в ListView.

Що я хочу, це відобразити a ProgressDialogпісля натискання кнопки пошуку, як "БУДЬ ЛАСКА, ЗАЧЕКАЙТЕ ... ОТРИМАННЯ ДАНИХ ..." або щось подібне і відхиліть це, коли відображаються дані.

public class Tab1Activity extends ListActivity {
private Button okButton;
private Button searchButton;
Toast toast;
String xml;

private TextView searchText;
private String searchTextString;
HashMap<String, String> o;
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tab1);

    searchButton = (Button) findViewById(R.id.search_button);
    searchButton.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            System.out.print("hello");

            searchText = (TextView) findViewById(R.id.search_text);
            searchTextString = searchText.getText().toString();
            readXml(searchTextString);

        }
    });

}

private void readXml(String searchTextString1) {
    ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

    String xml = XMLfunctions.getXML();
            //Here XMLfunctions is class name which parse xml
    Document doc = XMLfunctions.XMLfromString(xml);

    int numResults = XMLfunctions.numResults(doc);

    if ((numResults <= 0)) {
        Toast.makeText(Tab1Activity.this, "Testing xmlparser",
                Toast.LENGTH_LONG).show();
        finish();
    }

    NodeList nodes = doc.getElementsByTagName("result");

    for (int i = 0; i < nodes.getLength(); i++) {
        HashMap<String, String> map = new HashMap<String, String>();

        Element e = (Element) nodes.item(i);
        String nameMapString = XMLfunctions.getValue(e, "name");



         if ( nameMapString.toLowerCase().indexOf(searchTextString1.toLowerCase()) != -1 )   // != -1 means string is present in the search string
            {
                map.put("id", XMLfunctions.getValue(e, "id"));
                map.put("name",  XMLfunctions.getValue(e, "name"));
                map.put("Score",  XMLfunctions.getValue(e, "score"));
                mylist.add(map);
            }
    }

    ListAdapter adapter = new SimpleAdapter(this, mylist,
            R.layout.parsexml, new String[] { "name", "Score" }, new int[] {
                    R.id.item_title, R.id.item_subtitle });

    setListAdapter(adapter);

    final ListView lv = getListView();
    lv.setTextFilterEnabled(true);
    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            @SuppressWarnings("unchecked")
            HashMap<String, String> o = (HashMap<String, String>) lv
                    .getItemAtPosition(position);


                Toast.makeText(Tab1Activity.this,
                         "Name "+o.get("name")+"  Clicked", Toast.LENGTH_LONG)
                        .show();                

        }
    });
}

2
ProgressDialog застаріло з часів API Level O developer.android.com/reference/android/app/ProgressDialog.html
Варвара Калініна,

2
Там сказано: "Використовуйте індикатор прогресу, такий як ProgressBar, вбудований всередині діяльності, а не використовуючи цей модальний діалог". Чому вони просто не показують нам, як це робити? :)
Wolf359

Відповіді:


265

Оголосіть своє діалогове вікно прогресу:

ProgressDialog progress;

Коли ви будете готові розпочати діалогове вікно прогресу:

progress = ProgressDialog.show(this, "dialog title",
    "dialog message", true);

і щоб зникнути після закінчення:

progress.dismiss();

Ось невеликий приклад для вас:

// Note: declare ProgressDialog progress as a field in your class.

progress = ProgressDialog.show(this, "dialog title",
  "dialog message", true);

new Thread(new Runnable() {
  @Override
  public void run()
  {
    // do the thing that takes a long time

    runOnUiThread(new Runnable() {
      @Override
      public void run()
      {
        progress.dismiss();
      }
    });
  }
}).start();

Я написав код нижче, але не працює: 'searchButton.setOnClickListener (new View.OnClickListener () {public void onClick (View v) {// TODO Автоматично згенерований метод заглушки System.out.print ("привіт"); searchText = (TextView) findViewById (R.id.search_text); searchTextString = searchText.getText (). ToString (); progress.show (Tab1Activity.this, "Заголовок діалогового вікна", "Зачекайте ... завантаження"); readXml (searchTextString ); progress.dismiss ();}}); '
captaindroid

ну, це займає дуже малий час, як ви можете бачити вище, у мене також є метод readXML.
captaindroid

Цікаво, чи readXML працює так швидко, що ви не бачите діалогового вікна прогресу. якби ви робили щось через мережу, що насправді зайняло пару секунд - добре, перш за все, ви зробили б це в окремому потоці, але тоді ви побачите повний ефект діалогового вікна прогресу. якщо ви все-таки додасте потоки, переконайтеся, що ви showта dismissдіалогове вікно прогресу в потоці інтерфейсу.
dldnh

Але я думаю, що у нього є достатньо часу, щоб показати progressDialog. Коли я натиснув кнопку пошуку, це займає приблизно 2-3 секунди.
captaindroid

ви знаєте що, це, мабуть, тому readXML, що не дозволяє інтерфейсу перевести дух. можливо, ви захочете помістити його у свою власну тему - або з простими new Thread(...)(що я віддаю перевагу), або з AsyncTask, як пропонує Win Myo Htet.
dldnh

7

Я використовую наступний код в одному зі своїх поточних проектів, де я завантажую дані з Інтернету. Це все в моєму класі активності.

// ---------------------------- START DownloadFileAsync // -----------------------//
class DownloadFileAsync extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // DIALOG_DOWNLOAD_PROGRESS is defined as 0 at start of class
        showDialog(DIALOG_DOWNLOAD_PROGRESS);
    }

    @Override
    protected String doInBackground(String... urls) {
        try {
            String xmlUrl = urls[0];

            URL u = new URL(xmlUrl);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            int lengthOfFile = c.getContentLength();

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            long total = 0;

            while ((len1 = in.read(buffer)) > 0) {
                total += len1; // total = total + len1
                publishProgress("" + (int) ((total * 100) / lengthOfFile));
                xmlContent += buffer;
            }
        } catch (Exception e) {
            Log.d("Downloader", e.getMessage());
        }
        return null;
    }

    protected void onProgressUpdate(String... progress) {
        Log.d("ANDRO_ASYNC", progress[0]);
        mProgressDialog.setProgress(Integer.parseInt(progress[0]));
    }

    @Override
    protected void onPostExecute(String unused) {
        dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    }

}

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_DOWNLOAD_PROGRESS:
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Retrieving latest announcements...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(true);
        mProgressDialog.show();
        return mProgressDialog;
    default:
        return null;
    }

}

Орієнтація для мене змінилася просто чудово. Я щойно тестував у 2.3.3 AVD та на своєму ICS-телефоні.
the_gesslar

6

Створюючи об'єкт для індикатора прогресу, перевірте наступне.

Це не вдається:

dialog = new ProgressDialog(getApplicationContext());

При додаванні контексту діяльності працює ..

dialog = new ProgressDialog(MainActivity.this);

2

Не слід виконувати завдання, що вимагають великих ресурсів, у головному потоці. Це призведе до того, що користувальницький інтерфейс не реагує, і ви отримаєте ANR. Здається, ви будете займатися ресурсоємними справами і хочете, щоб користувач бачив ProgressDialog. Ви можете заглянути на http://developer.android.com/reference/android/os/AsyncTask.html, щоб виконувати завдання, що вимагають значних ресурсів. Він також показує, як користуватися a ProgressDialog.


1

Я використовую наступний код в одному зі своїх поточних проектів, де я завантажую дані з Інтернету. Це все в моєму класі активності.

private class GetData extends AsyncTask<String, Void, JSONObject> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = ProgressDialog.show(Calendar.this,
                    "", "");

        }

        @Override
        protected JSONObject doInBackground(String... params) {

            String response;

            try {

                HttpClient httpclient = new DefaultHttpClient();

                HttpPost httppost = new HttpPost(url);

                HttpResponse responce = httpclient.execute(httppost);

                HttpEntity httpEntity = responce.getEntity();

                response = EntityUtils.toString(httpEntity);

                Log.d("response is", response);

                return new JSONObject(response);

            } catch (Exception ex) {

                ex.printStackTrace();

            }

            return null;
        }

        @Override
        protected void onPostExecute(JSONObject result) 
        {
            super.onPostExecute(result);

            progressDialog.dismiss();

            if(result != null)
            {
                try
                {
                    JSONObject jobj = result.getJSONObject("result");

                    String status = jobj.getString("status");

                    if(status.equals("true"))
                    {
                        JSONArray array = jobj.getJSONArray("data");

                        for(int x = 0; x < array.length(); x++)
                        {
                            HashMap<String, String> map = new HashMap<String, String>();

                            map.put("name", array.getJSONObject(x).getString("name"));

                            map.put("date", array.getJSONObject(x).getString("date"));

                            map.put("description", array.getJSONObject(x).getString("description"));

                            list.add(map);
                        }

                        CalendarAdapter adapter = new CalendarAdapter(Calendar.this, list);

                        list_of_calendar.setAdapter(adapter);
                    }
                }
                catch (Exception e) 
                {
                    e.printStackTrace();
                }
            }
            else
            {
                Toast.makeText(Calendar.this, "Network Problem", Toast.LENGTH_LONG).show();
            }
        }

    }

і виконайте його в методі OnCreate, як new GetData().execute();

де Calendar - це моя календарна діяльність, і я також створив CalendarAdapter для встановлення цих значень у вигляді списку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.