2011-04-08 54 views
4

我有一個JSON文件被填充到列表視圖。Android:製作動態列表視圖

我想使列表視圖動態。這意味着,我只需要一個活動來進行列表中的點擊操作。內容的來源(圖片,標題,說明)填充到活動來自Web上的JSON文件。

例如,我有13個項目在列表中,每當我點擊其中一個時,它會轉到一個包含不同圖片,標題和描述的活動取決於我點擊的項目。

我需要某人來改進我在下面提供的代碼。

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(我不認爲我們需要編輯此一)

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); 
     } 
    } 


} 

編輯 我想秀Organization.java是這樣的.xml文件:

<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> 

這裏是JSON文件:

[{ 
    "title": "CARE Deutschland-Luxemburg e.V.", 
    "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" 
}] 

列表視圖的屏幕截圖: enter image description here

如果這些是我必須做的,那麼我在使用數4 & 5麻煩步驟: 1.讓JSON 2.構建物的合適的數據結構(一個陣列,ArrayList中,不管你喜歡)以保存關於您的列表視圖的關鍵數據 3.使用此數據結構作爲您的列表視圖的來源 4.當用戶單擊任何行時,嘗試找到列表視圖中該行的位置,在您的源數據結構中的位置,查找所需的數據。 5.創建其處理這些數據一般 6.打開活動與用戶在步驟4單擊7. 在新的活動消耗這個數據

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()); 
     } 
    } 


} 

如果有什麼不清楚的地方,請告訴我。 非常感謝您

回答

2

對於你需要持有指數所有的JSON節點的數據結構,它應該是所有你需要的活動訪問[RECO:使用這樣的,你有你的項目GlobalVariables或ConstantData屬性,並使其public static]。

:ConstantData.projectData這可能是隻包含項目的數組列表或數組對象現在

  1. 從列表視圖onItemClick方法,你會得到一個指數(position即表示其行其點擊) ,請在捆綁和附加內容的幫助下通過單一設計的活動傳遞此信息。

2.獲取所需活動的索引。從ConstantData.projectData中獲取該索引的項目對象。

填充項目對象中的UI組件。

這樣做,你可以一次又一次地膨脹同樣的觀點是隻透過指數,僅填充列表可以是一個繁重的操作,但其餘的會更快....

編輯:讓我爲您提供片段。

爲1. Main.java你使用這些線itemClick在方法

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

加入startActivity和意圖初始化之間的這條線。

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

爲2.在Organization.java 2.1創建名爲mPosition的整數構件[或你喜歡的名字] 2.2 onCreate()方法寫mPosition = getIntent().getExtras().getInt("yourPackageStructure.Organization.position");

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

,因爲我不知道Organization.java中的內容,我想說一個數組列表或者包含您的Projects對象的東西。

這裏是你可以有Organization.java的onCreate方法。

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); 

} 

這是我使用的方法getImageFromUrl

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; 
    } 

這是haveInternet方法

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; 
    } 

希望能有助於你正確...

新增ConstantData

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>(); 
} 
如果要填充你可以做這個數組列表main.java檢查線路

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

您可以添加或更換此行

ConstantData.projectsList.add(l);我建議您添加行,而不是顯示行.....

+0

謝謝。我已經在Projects上擁有了所有JSON節點的數據結構。java,我發佈在頂端的代碼。你能通過提供代碼找到我的解決方案嗎? thx – hectichavana 2011-04-08 13:08:42

+0

編輯我的答案..看看 – Prasham 2011-04-08 13:31:08

+0

感謝它變得更清晰,我剛剛編輯我的問題,提供Organization.java的XML文件看看.. – hectichavana 2011-04-08 14:05:13