Several optimizations when using ListView to create an App Store in Android

Source: Internet
Author: User

Several optimizations when using ListView to create an App Store in Android
Package com. example. ex01_1; import java. io. file; import java. io. fileOutputStream; import java. io. IOException; import java. io. inputStream; import java.net. malformedURLException; import java.net. URL; import java.net. URLConnection; import java. util. arrayList; import java. util. hashMap; import android. OS. asyncTask; import android. OS. bundle; import android. OS. environment; import android. app. activity; import android. App. alertDialog; import android. app. notification; import android. app. icationicationmanager; import android. content. context; import android. content. dialogInterface; import android. database. cursorJoiner. result; import android. graphics. bitmap; import android. graphics. bitmapFactory; import android. util. log; import android. view. layoutInflater; import android. view. menu; import android. view. menuItem; import android. vi Ew. view; import android. view. view. onClickListener; import android. view. viewGroup; import android. widget. arrayAdapter; import android. widget. baseAdapter; import android. widget. button; import android. widget. imageView; import android. widget. listView; import android. widget. progressBar; import android. widget. textView; import android. widget. toast; public class MainActivity <E> extends Activity {private ArrayList <S Tring> dataList = new ArrayList <String> (); private ArrayList <String> fileurl = new ArrayList <String> (); private MyAdapater myadapater; // String PATH = "http: // 192.168.56.1: 8080/server/"; String PATH =" http: // 192.168.56.1: 8080/server/"; private ListView listView;/** problem: Image download is complete, slide the ListView up and down, and the reason for downloading the image again: slide up and down, trigger the getView () method, create an asynchronous task, and download again. Solution: Create a container, save the downloaded Bitmap object * // to prevent repeated downloads, put the downloaded image in the imgmap container HashMap <Strin G, Bitmap> imgmap = new HashMap <String, Bitmap> ();/*** problem: During the download process, slide the ListView up and down and wait until the download is complete. The reason for the image is downloaded multiple times: slide the ListView up and down and trigger the getView () method to determine whether the image has not been downloaded. Create a New asynchronous task to solve the problem: create a container to save the AsyncTask object that has been started ** // create a container to save the started asynchronous task HashMap <String, ImgAsy> asymap = new HashMap <String, imgAsy> ();/** the problem is: after a row is downloaded, slide the ListView up and down. * The status of the previous row appears for other lines that have not clicked to download. By referencing the container to save the file download status, we can solve this problem by updating the control status based on the differences in the download status. * /// Create a container to save the Download Status of the file in the current row. When downloading the file, reuse the BugHashMap <Integer, Boolean> stateMap = new HashMap <Integer, boolean> (); @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); // first find listView1listView = (ListView) findViewById (R. id. listView1); myadapater = new MyAdapater (); listView. setAdapter (myadapater ); // Add the image for (int I = 1; I <16; I ++) {dataList. add (PATH + "ic" + I + ". png ");} // Add the file for (int I = 1; I <16; I ++) {fileurl. add (PATH + "ic" + I + ". rar ") ;}} // get the private String getSavePath (String fileurl) {String sdcard = Environment. getExternalStorageDirectory () + ""; // intercept a segment of address int lastIndexOf = fileurl. lastIndexOf ("/"); String savename = fileurl. substring (lastIndexOf); String savePath = sdcard + Savename; return savePath;} // create an adapter class MyAdapater extends BaseAdapter {private ImgAsy asy; // obtain the number of rows @ Overridepublic int getCount () {return 15 ;} @ Overridepublic Object getItem (int position) {return null ;}@ Overridepublic long getItemId (int position) {return 0 ;}@ Override // get the style and content of each row of controls, modify the content and style of each row of the control. Here, public View getView (final int position, View convertView, ViewGroup parent) {View View = null; ViewHolder holder = null; // continue optimization, optimize the 1 reuse layout to prevent repeated downloads and waste unnecessary traffic if (convertView = null) // convertView: disappear row layout {// find the XML file converter LayoutInflater inflater = getLayoutInflater (); // convert the style of each row to VIEW object view = inflater. inflate (R. layout. listview, null); // optimize 2 to reduce the widget search. encapsulate a class containing all controls holder = new ViewHolder (); holder. iv = (ImageView) view. findViewById (R. id. imageView1); holder. btn = (Button) view. findViewById (R. Id. button1); holder. TV = (TextView) view. findViewById (R. id. textView1); holder. pb = (ProgressBar) view. findViewById (R. id. progressBar1); view. setTag (holder);} else {view = convertView; holder = (ViewHolder) view. getTag (); // optimized 2}/** problem: After a row of ListView is downloaded, slide the ListView up and down. The number of rows that have not yet been downloaded shows the image cause: Reuse causes the solution: for the number of rows that have not been downloaded, set the default image display * // set the image of the row that has not been downloaded to the default image to solve the problem of holder displaying undownloaded images in advance. iv. setImageResource (R. drawable. ic_launcher); // The two lines of code are Bitmap bitmap = imgmap written to determine whether the current row of images is downloaded and whether the asynchronous task is enabled. get (dataList. get (position); ImgAsy asy = asymap. get (dataList. get (position); if (bitmap = null) {// The image has not been downloaded. Determine whether the asynchronous task of the current row starts if (asy = null) {// This is a constructor asy = new ImgAsy (holder. iv, position); asy.exe cute (dataList. get (position); asymap. put (dataList. get (position), asy) ;}// solve the problem that the ImageView object was created but no new asynchronous task was created during the upper and lower Sliding Process. Asy. changView (holder. iv);} else {holder. iv. setImageBitmap (bitmap);} // set the display status of each control based on the download status. Boolean state = stateMap. get (position); if (state = null) {holder. btn. setEnabled (true); holder. pb. setProgress (0); holder. TV. setText ("not downloaded"); holder. btn. setText ("Download");} else {if (state = true) {holder. btn. setEnabled (false); holder. pb. setProgress (100); holder. TV. setText ("download completed"); holder. btn. setText ("download completed");} else {Holder. btn. setEnabled (false); holder. TV. setText ("downloading"); holder. btn. setText ("downloading") ;}} final ProgressBar pb = holder. pb; final TextView TV = holder. TV; final Button btn = holder. btn; // use an anonymous internal class to write the event holder of the button listening event. btn. setOnClickListener (new OnClickListener () {public void onClick (View v) {// create a file download asynchronous event and enable FileAsy fileAsy = new FileAsy (TV, pb, btn, position ); fileAsy.exe cute (fileurl. get (position ));/ /Carries the row number. }); Return view ;}/// asynchronous task class FileAsy extends AsyncTask for File Download <String, Integer, String >{ TextView TV; ProgressBar pb; Button btn; // pass the Button into the asynchronous task of downloading the object. In order to control the state of the Button, private int position; public FileAsy (TextView TV, ProgressBar pb, Button btn, int position) {super (); this. TV = TV; this. pb = pb; this. btn = btn; this. position = position;} // save path String savepath = Environment. getExternal StorageDirectory () + "/wenjian.apk"; private String result; // run @ Override protected void onPreExecute () {btn before doInBackgound. setEnabled (false); btn. setText ("Download"); stateMap. put (position, false); // The download status of each row of the file is super. onPreExecute () ;}@ SuppressWarnings ("resource") @ Override protected String doInBackground (String... params) {try {URL url = new URL (params [0]); // open the url URLConnection connection = URL. OpenConnection (); int length = connection. getContentLength (); InputStream is = connection. getInputStream (); // File file = new File (savepath); String savePath2 = getSavePath (params [0]); FileOutputStream fos = new FileOutputStream (savePath2 ); byte [] buffer = new byte [1024]; int len = 0; int dllength = 0; // write it here while (-1! = (Len = is. read (buffer) // read the data first {fos. write (buffer, 0, len); // write data in/push progress dllength + = len; publishProgress (dllength * 100/length);} catch (MalformedURLException e) {e. printStackTrace ();} catch (IOException e) {result = "Download failed"; e. printStackTrace ();} result = "Download succeeded"; return result;} protected void onProgressUpdate (Integer... values) {// This judgment statement is used to solve the BUG: During the file download process, the LiseView is slowly slide up and down, and the row without clicking download appears The download status. // As long as the current row of the Button goes if (isVisiablePositon (listView, position) {pb. setProgress (values [0]); TV. setText ("downloaded" + values [0] + "%");} super. onProgressUpdate (values);} // After downloading, update the image protected void onPostExecute (String result) {Toast. makeText (MainActivity. this, result, Toast. LENGTH_SHORT ). show (); if (isVisiablePositon (listView, position) {btn. setEnabled (true); btn. setText ("download completed");} stateMap. put (po Sition, true); super. onPostExecute (result) ;}}// download the image class ImgAsy extends AsyncTask <String, Void, Bitmap> {private Bitmap bitmap; private ImageView iv; private int position; // Add the parameter public ImgAsy (ImageView iv, int position) {super (); this. iv = iv; this. position = position;}/*** problem: During the download process, slide the ListView up and down and wait until the download is complete. The reason for not displaying the images of some rows is: slide the ListView up and down, create a new ImageView object without creating a new AsyncTask. Solution: 1. write a method and send it to AsyncTas again. In k, the ImageView value * notifies AsyncTask to update the ImageView object * 2. call */public void changView (ImageView iv) {this. iv = iv ;}@ Override protected Bitmap doInBackground (String... params) {try {URL url = new URL (params [0]); InputStream is = url. openStream (); // bitmap = BitmapFactory. decodeStream (is); // download bitmap} catch (MalformedURLException e) {// TODO Auto-generated catch block e. printStackTrace ();} catc H (IOException e) {// TODO Auto-generated catch block e. printStackTrace ();} return bitmap; // equivalent to handlermessage} // After the download is complete, update the Image Based on the Bitmap (written in the internal class) protected void onPostExecute (bitmap) {isVisiablePositon (listView, position); if (isVisiablePositon (listView, position) {iv. setImageBitmap (bitmap);} imgmap. put (dataList. get (position), bitmap); // save super. onPostExecute (bitmap) ;}// write a method to determine whether the current row is visible. Update data only in the current row. The return value is 'boolean' type 'public Boolean isVisiablePositon (ListView listView, int position) {// obtain the row number of the first line of the visible row: int fp = listView. getFirstVisiblePosition (); // obtain the row number int lp = listView for the last row of the visible row. getLastVisiblePosition (); // Add position in the constructor // determine whether the current row is within the visible range if (position> = fp & position <= lp) {// Let the visible row update the control // iv. setImageBitmap (bitmap); return true; // return true, end method} return false;} // optimize 2 to reduce the query of the control. encapsulate a class containing all controls class ViewHolder {ImageView iv; Button btn; TextView TV; ProgressBar pb; }}1 <br>

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.