Android:制作动态 ListView

标签 android listview dynamic

我有一个填充到 ListView 的 JSON 文件。

我想让 ListView 动态化。这意味着,我只需要一个 Activity 来执行列表中的单击操作。填充到 Activity 的内容(图片、标题、描述)的来源来自网络上的 JSON 文件。

例如,我在列表中有 13 个项目,每当我单击其中一个项目时,它就会转到一个包含不同图片、标题和描述的 Activity ,具体取决于我单击的项目。

我需要有人改进我在下面提供的代码。

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

}

主.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"
}]

ListView 截图: enter image description here

如果这些是我必须执行的步骤,那么我在处理第 4 和第 5 步时遇到了问题: 1. 拥有 JSON 2. 构造一个合适的数据结构(Array、ArrayList,任何你喜欢的)来保存关于你的 ListView 的关键数据 3. 使用此数据结构作为 ListView 的来源 4. 当用户点击任意行时,尝试找出该行在 ListView 中的位置,并在源数据结构中的该位置上查找所需的数据。 5. 创建一般处理这些数据的任何 Activity 6. 使用用户在第 4 步中单击的行的数据打开该 Activity 7. 在您的新 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());
        }
    }


}

如果有什么不明白的,请告诉我。 非常感谢

最佳答案

为此,您需要一个数据结构,将所有 json 节点保存在索引上,并且您需要的所有 Activity 都可以访问它 [Reco:使用诸如 GlobalVariables 或 ConstantData 之类的东西,您可以在其中拥有所有项目属性并使其成为 公共(public)静态].

喜欢 : ConstantData.projectData 可以是只包含Project对象的arraylist或array

  1. 现在,从 ListView 的 onItemClick 方法中,您将获得一个索引(position,表示它点击了哪一行),借助 bundle 和 extras 将其传递给您设计的单个 Activity 。

2.在您想要的 Activity 中获取索引。从 ConstantData.projectData 获取该索引上的项目对象。

从您的项目对象填充 UI 组件。

通过这样做,您可以仅通过索引一次又一次地膨胀相同的 View ,仅填充列表可能是一项繁重的操作,但其余的会更快....

编辑:让我为您提供 fragment 。

对于 1. 在 Main.java 上,您在 itemClick 方法中使用这些行

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

在 startActivity 和 Intent 初始化之间添加这一行。

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 中有什么,所以我想说一个数组列表或保存您的项目对象的东西。

这是您可以拥有的 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.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); 我建议您添加该行而不是显示该行.....

关于Android:制作动态 ListView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5595048/

相关文章:

android - 如何在 Android 中的不同 Activity/Fragment 之间保持相同的 session ?

显示 toast 的 Android 服务

java - Listview onclick 中的 TextView 冲突

javascript - 你如何动态地添加一个按钮/插件到 TinyMCE?

c# - 如何以编程方式设置动态创建以嵌入到 TableLayoutPanel 中的控件的 Column 和 Row 属性?

javascript - 如何在静态 Javascript 中嵌入 EJS 代码?

android - 如何在我的 Android 应用程序中简单地在屏幕上滑动来更改 'tabs'?就像 Google+ Android 应用一样

android - HTC 设备 adb 错误

flutter - LimitedBox 与 ConstrainedBox 中的 ListView

android - 向上滚动时在 ListView 中显示底部按钮栏,向下滚动时隐藏