Android: creating a dynamic list

I have a JSON file that is populated with a list.

I want to make a dynamic list view. This means that I only need one action for the click action in the list that I have. And the content source (image, title, description) that is populated for the Activity comes from a JSON file on the Internet.

For example, I have 13 projects in the list, every time I click one of them, it goes to ONE activity containing a different image, title and description, depending on the element that I click.

I need someone to improve the codes below.

Projects.java

public class Projects { public String title; public String keyword; public String description; public String smallImageUrl; public String bigImageUrl; public int cost; @Override public String toString() { return "Title: "+title+ " Keyword: "+keyword+ " Image: "+smallImageUrl; } } 

ProjectsAdapter.java

 Public class ProjectsAdapter extends ArrayAdapter<Projects> { int resource; String response; Context context; //Initialize adapter public ProjectsAdapter(Context context, int resource, List<Projects> items) { super(context, resource, items); this.resource=resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { LinearLayout projectView; //Get the current alert object Projects pro = getItem(position); //Inflate the view if(convertView==null) { projectView = new LinearLayout(getContext()); String inflater = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater vi; vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, projectView, true); } else { projectView = (LinearLayout) convertView; } TextView Title =(TextView)projectView.findViewById(R.id.title); try { ImageView i = (ImageView)projectView.findViewById(R.id.image); Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(pro.smallImageUrl).getContent()); i.setImageBitmap(bitmap); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //Assign the appropriate data from our alert object above //Image.setImageDrawable(pro.smallImageUrl); Title.setText(pro.title); return projectView; } } 

Main.java

 public class Main extends Activity { /** Called when the activity is first created. */ //ListView that will hold our items references back to main.xml ListView lstTest; //Array Adapter that will hold our ArrayList and display the items on the ListView ProjectsAdapter arrayAdapter; //List that will host our items and allow us to modify that array adapter ArrayList<Projects> prjcts=null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Initialize ListView lstTest= (ListView)findViewById(R.id.lstText); //Initialize our ArrayList prjcts = new ArrayList<Projects>(); //Initialize our array adapter notice how it references the listitems.xml layout arrayAdapter = new ProjectsAdapter(Main.this, R.layout.listitems,prjcts); //Set the above adapter as the adapter of choice for our list lstTest.setAdapter(arrayAdapter); //Instantiate the Web Service Class with he URL of the web service not that you must pass WebService webService = new WebService("http://pre.spendino.de/test/android/projects.json"); //Pass the parameters if needed , if not then pass dummy one as follows Map<String, String> params = new HashMap<String, String>(); params.put("var", ""); //Get JSON response from server the "" are where the method name would normally go if needed example // webService.webGet("getMoreAllerts", params); String response = webService.webGet("", params); try { //Parse Response into our object Type collectionType = new TypeToken<ArrayList<Projects>>(){}.getType(); //JSON expects an list so can't use our ArrayList from the lstart List<Projects> lst= new Gson().fromJson(response, collectionType); //Now that we have that list lets add it to the ArrayList which will hold our items. for(Projects l : lst) { prjcts.add(l); } //Since we've modified the arrayList we now need to notify the adapter that //its data has changed so that it updates the UI arrayAdapter.notifyDataSetChanged(); } catch(Exception e) { Log.d("Error: ", e.getMessage()); } lstTest.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { @SuppressWarnings("unchecked") Projects p = (Projects ) lstTest.getItemAtPosition(position); //Do your logic and open up a new Activity. Intent care = new Intent(Main.this, Organization.class); startActivity(care); } }); } } 

WebService.java (I don't think we need to edit this)

 public class WebService{ DefaultHttpClient httpClient; HttpContext localContext; private String ret; HttpResponse response1 = null; HttpPost httpPost = null; HttpGet httpGet = null; String webServiceUrl; //The serviceName should be the name of the Service you are going to be using. public WebService(String serviceName){ HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, 10000); HttpConnectionParams.setSoTimeout(myParams, 10000); httpClient = new DefaultHttpClient(myParams); localContext = new BasicHttpContext(); webServiceUrl = serviceName; } //Use this method to do a HttpPost\WebInvoke on a Web Service public String webInvoke(String methodName, Map<String, Object> params) { JSONObject jsonObject = new JSONObject(); for (Map.Entry<String, Object> param : params.entrySet()){ try { jsonObject.put(param.getKey(), param.getValue()); } catch (JSONException e) { Log.e("Groshie", "JSONException : "+e); } } return webInvoke(methodName, jsonObject.toString(), "application/json"); } private String webInvoke(String methodName, String data, String contentType) { ret = null; httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); httpPost = new HttpPost(webServiceUrl + methodName); response1 = null; StringEntity tmp = null; //httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE"); httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); if (contentType != null) { httpPost.setHeader("Content-Type", contentType); } else { httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); } try { tmp = new StringEntity(data,"UTF-8"); } catch (UnsupportedEncodingException e) { Log.e("Groshie", "HttpUtils : UnsupportedEncodingException : "+e); } httpPost.setEntity(tmp); Log.d("Groshie", webServiceUrl + "?" + data); try { response1 = httpClient.execute(httpPost,localContext); if (response1 != null) { ret = EntityUtils.toString(response1.getEntity()); } } catch (Exception e) { Log.e("Groshie", "HttpUtils: " + e); } return ret; } //Use this method to do a HttpGet/WebGet on the web service public String webGet(String methodName, Map<String, String> params) { String getUrl = webServiceUrl + methodName; int i = 0; for (Map.Entry<String, String> param : params.entrySet()) { if(i == 0){ getUrl += "?"; } else{ getUrl += "&"; } try { getUrl += param.getKey() + "=" + URLEncoder.encode(param.getValue(),"UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } i++; } httpGet = new HttpGet(getUrl); Log.e("WebGetURL: ",getUrl); try { response1 = httpClient.execute(httpGet); } catch (Exception e) { Log.e("Groshie:", e.getMessage()); } // we assume that the response body contains the error message try { ret = EntityUtils.toString(response1.getEntity()); } catch (IOException e) { Log.e("Groshie:", e.getMessage()); } return ret; } public static JSONObject Object(Object o){ try { return new JSONObject(new Gson().toJson(o)); } catch (JSONException e) { e.printStackTrace(); } return null; } public InputStream getHttpStream(String urlString) throws IOException { InputStream in = null; int response = -1; URL url = new URL(urlString); URLConnection conn = url.openConnection(); if (!(conn instanceof HttpURLConnection)) throw new IOException("Not an HTTP connection"); try{ HttpURLConnection httpConn = (HttpURLConnection) conn; httpConn.setAllowUserInteraction(false); httpConn.setInstanceFollowRedirects(true); httpConn.setRequestMethod("GET"); httpConn.connect(); response = httpConn.getResponseCode(); if (response == HttpURLConnection.HTTP_OK) { in = httpConn.getInputStream(); } } catch (Exception e) { throw new IOException("Error connecting"); } // end try-catch return in; } public void clearCookies() { httpClient.getCookieStore().clear(); } public void abort() { try { if (httpClient != null) { System.out.println("Abort."); httpPost.abort(); } } catch (Exception e) { System.out.println("Your App Name Here" + e); } } } 

EDIT I want to show this .xml file in Organization.java:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/bg" android:orientation="vertical"> <ImageView android:id="@+id/project_image" android:layout_marginTop="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="Default Title" android:textSize="18sp" android:textStyle="bold" android:textColor="#78b257"/> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_marginTop="15dp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <Button android:id="@+id/btn_forward" android:layout_marginLeft="5dp" android:layout_gravity="left" android:text="Weitersagen" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="15dp"/> <Button android:id="@+id/btn_sms_spend" android:layout_marginTop="15dp" android:layout_marginRight="5dp" android:text="Per SMS spenden" android:layout_gravity="right" android:layout_height="wrap_content" android:layout_width="wrap_content"/> </LinearLayout> <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/bg_white" android:orientation="vertical"> <TextView android:id="@+id/description" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_marginLeft="5dp" android:gravity="left" android:text="default description" android:textSize="18sp" android:textColor="#000000"/> </LinearLayout> </ScrollView> </LinearLayout> 

and here is the JSON file:

 [{ "title": "CARE Deutschland-Luxemburg eV", "keyword": "CARE", "description": "<p><b>Das CARE-Komplett-Paket für Menschen in Not</b", "smallImageUrl": "http://cdn.spendino.de/web/img/projects/home/1284113658.jpg", "bigImageUrl":"http://cdn.spendino.de/web/img/projects/small/1284113658.jpg", "cost": "5" }, { "title": "Brot für die Welt", "keyword": "BROT", "description": "<p>„Brot für die Welt" unterstützt unter der Maßgabe 'Helfen, wo die Not am größten ist' ausgewählte Projekte weltweit.", "smallImageUrl": "http://cdn.spendino.de/web/img/projects/home/1267454286.jpg", "bigImageUrl":"http://cdn.spendino.de/web/img/projects/small/1267454286.jpg", "cost": "5" }, { "title": "Deutsche AIDS-Stiftung", "keyword": "HIV", "description": "<p>Die Deutsche AIDS-Stiftung unterstützt mit ihren finanziellen Mitteln seit mehr als 20 Jahren Betroffene, die an HIV und AIDS erkrankt sind.", "smallImageUrl": "http://cdn.spendino.de/web/img/projects/home/1258365722.jpg", "bigImageUrl":"http://cdn.spendino.de/web/img/projects/small/1258365722.jpg", "cost": "5" }] 

Screenshot from the list: enter image description here

If these are the steps that I should take, I am having problems with numbers 4 and 5: 1. Have JSON 2. build a suitable data structure (Array, ArrayList, as you like) to store important data about your list view 3. Use this data structure as a source for viewing the list. 4. When the user clicks on any row, try to find the position of the row in the list view and at that position in your original data structure, find the necessary data. 5. create any activity that processes this data as a whole 6. Open this action with the data of the line that the user clicked on step 4 7. Use this data in your new activity.

Constantdata.java

 public class ConstantData extends ArrayList<Projects>{ private static final long serialVersionUID = 9100099012485622682L; public static Object projectsList; public ConstantData(){ } public ConstantData(Parcel in){ } @SuppressWarnings("unchecked") public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){ public ConstantData createFromParcel (Parcel in){ return new ConstantData(in); } public Object[] newArray(int arg0){ return null; } }; private void readFromParcel(Parcel in){ this.clear(); int size = in.readInt(); for (int i = 0; i < size; i++){ Projects p = new Projects(); p.setTitle(in.readString()); p.setKeyword(in.readString()); p.setSmallImageUrl(in.readString()); p.setBigImageUrl(in.readString()); p.setCost(in.readInt()); } } public int describeContents() { return 0; } public void writeToParcel (Parcel dest, int flags){ int size = this.size(); dest.writeInt(size); for (int i = 0; i < size; i++){ Projects p = this.get(i); dest.writeString(p.getTitle()); dest.writeString(p.getKeyword()); dest.writeString(p.getDescription()); dest.writeString(p.getSmallImageUrl()); dest.writeString(p.getBigImageUrl()); dest.writeInt(p.getCost()); } } } 

If something is unclear, let me know. Thank you very much

+4
source share
1 answer

To do this, you need a data structure that contains all of your json nodes in the index, and it must be available for all necessary actions. [Reco: use something like GlobalVariables or ConstantData where you have all your project properties and do it public static ].

Like : ConstantData.projectData, which can be an array or an array that contains only Project objects

  • Now, from the view of the onItemClick list, you will get an index ( position , which indicates which line it was clicked on), pass it on in your separate planned activity using packages and add-ons.

2. Extract the index into the desired activity. Extract the project object from this index from ConstantData.projectData.

Fill in the user interface components from the project object.

This way you can inflate the same view over and over, just passing in an index, only populating a list can be a tough operation, but the rest will be faster.

Change Let me provide you with snippets.

for 1. on Main.java you use this line in itemClick methods

 Intent care = new Intent(Main.this, Organization.class); startActivity(care); 

Add this line between the initialization of startActivity and Intent.

 care.putExtra("yourPackageStructure.Organization.position",position); 

for 2. In Organization.java 2.1, create an integer member called mPosition [or a name you like] 2.2 in the onCreate () method write mPosition = getIntent().getExtras().getInt("yourPackageStructure.Organization.position");

 Project project = ConstantData.projectsData.get(mPosition); 

Like I don't know how this happens in Organization.java, and I wanted to say a list of arrays or something that contains Project objects.

Here is what you can have on Organization.java onCreate method.

 onCreate(){ position = getIntent().getExtras().getInt("yourPackageStructure.Organization.position"); //Below line will get you the projects object Projects project = ConstantData.projectsList.itemAt(position); ImageView projectImage = (ImageView)findViewById(R.id.project_image); Bitmap image = getImageFromUrl(this,project.bigImageUrl); projectImage.setBitmapDrawable(image); TextView title = (TextView)findViewById(R.id.title); title.setText(project.title); TextView description = (TextView)findViewById(R.id.description); description .setText(project.description); } 

This is what I use for the getImageFromUrl method

 public static Bitmap getImageFromUrl(Context context, String urlString) { try { if (haveInternet(context)) { URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setDoInput(true); conn.connect(); int length = conn.getContentLength(); InputStream is = conn.getInputStream(); Bitmap bmImg = BitmapFactory.decodeStream(is); return bmImg; } else { return null; } } catch (MalformedURLException e) { Log.e("Problem in image", e.toString(), e); e.printStackTrace(); } catch (Exception e) { Log.e("Problem in image", e.toString(), e); } return null; } 

This is the hasInternet method

 private static boolean haveInternet(Context context) { NetworkInfo info = getNetworkInfo(context); if (info == null || !info.isConnected()) { return false; } if (info.isRoaming()) { // here is the roaming option you can change it if you want to // disable internet while roaming, just return false return true; } return true; } 

Hoping this helps you correctly ...

Added by ConstantData p>

Constantdata.java

 public class ConstantData{ //All public static members will be here public static final long guid = A LONG VAL; public static String licenceText = A STRING VAL; //etc... etc... above members are just the idea that what kind of members can be there in //ConstantData... I normally use all public static properties here //Here is the variable you probably want public static ArrayList<Projects> projectsList = new ArrayList<Projets>(); } 

if you want to fill this list of arrays you can do it with main.java check the lines

 for(Projects l : lst) { prjcts.add(l); } 

You can add or replace this line. ConstantData.projectsList.add(l); I recommend you add a line rather to display a line .....

+2
source

Source: https://habr.com/ru/post/1347241/


All Articles