ListView:使用JSON中的图像填充listview

时间:2015-02-21 03:07:32

标签: php android json listview android-listview

我有一个listview,在通过Php / JSON显示数据库中的所有文本时非常有效。但是,在数据库中,有一个与我希望在列表视图中显示的每个项目相关联的图像链接。基本上它的作用是一个人点击搜索按钮,操作菜单中的默认android搜索栏出现在他们输入单词的位置。然后它进入服务器并发送单词并尝试从数据库中找到所有匹配并拉出它。现在它与显示文本视图完美配合但由于某种原因我无法显示图像。有人能告诉我它是怎么做到的吗?我尝试了几次但是我失败了,因此我提供给你的代码是我的最新代码:

public class ListResult extends ListActivity {

    // Progress Dialog
    private ProgressDialog pDialog;

    // Creating JSON Parser object
    JSONParser jParser = new JSONParser();

    ArrayList<HashMap<String, String>> UserBooksList;

    // url to get the idiom list
    private static String url_search =   
    "http://randomurl.com/arandomapp/search.php";

    // JSON Node names
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_UserBooks = "UserBooks";
    private static final String TAG_BName = "BName";
    private static final String TAG_NAME = "name";

    // THIS TAG BELOW IS THE ONE WHICH SHOWS THE IMAGE URL.
    private static final String TAG_IMG = "Id";

    // products JSONArray
    JSONArray user_books = null;

    // The keyword send to server and displays the result.
    public String search_key;

    TextView mError;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_result);

    // get the action bar
    ActionBar actionBar = getActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);

    if (savedInstanceState == null) {
        Bundle extras = getIntent().getExtras();
        if(extras == null) {
            search_key = null;
        } else {
            search_key = extras.getString("keyword");
        }
    } else {
        search_key = (String) savedInstanceState.getSerializable("keyword");
    }

    UserBooksList = new ArrayList<>();

    // Loading idioms in Background Thread
    new LoadIdioms().execute();

    mError = (TextView) findViewById(R.id.error);
    mError.setVisibility(View.GONE);

    actionBar.setTitle("Relevant Searches For: " + search_key);
    actionBar.setIcon(R.drawable.ic_action_search);
}

class LoadIdioms extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(ListResult.this);
        pDialog.setMessage("Loading Data. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    protected String doInBackground(String... args) {

        // Building Parameters
        List<NameValuePair> params = new ArrayList<>();

        //value captured from previous intent
        params.add(new BasicNameValuePair("keyword", search_key));

        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_search, "GET",    
params);

        try {

            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {

                user_books = json.getJSONArray(TAG_UserBooks);

                for (int i = 0; i < user_books.length(); i++) {
                    JSONObject c = user_books.getJSONObject(i);

                    // Storing each json item in variable
                    String bName = c.getString(TAG_BName);
                    String Name = c.getString(TAG_NAME);
                    String b_img = c.getString(TAG_IMG);

                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<>();

                    // adding each child node to HashMap key => value
                    map.put(TAG_BName, bName);
                    map.put(Tag_NAME, Name);
                    map.put(TAG_IMG, b_img);

                    // adding HashList to ArrayList
                    UserBooksList.add(map);

                }
            } else {
                Log.d("Login Failure!", json.getString(TAG_MESSAGE));
                return json.getString(TAG_MESSAGE);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(String file_url) {

        // dismiss the dialog after getting the related idioms
        pDialog.dismiss();

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {

            public void run() {
                /**
                 * Updating parsed JSON data into ListView
                 **/

                ListAdapter adapter = new SimpleAdapter(
                        ListResult.this, UserBooksList,
                        R.layout.list_item, new String[] {TAG_BName, TAG_Name},
                        new int[] {R.id.BName, R.id.Name});

                // updating listview
                setListAdapter(adapter);
            }
        });

        // dismiss the dialog once product deleted
        pDialog.dismiss();
        if (file_url != null){
            mError = (TextView) findViewById(R.id.error);
            mError.setVisibility(View.VISIBLE);
            mError.setText("Sorry, No Books were found. Please try again.");
        }
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.activity_main_actions_two, menu);

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Take appropriate action for each action item click
    switch (item.getItemId()) {
        case R.id.action_help:
            // help action
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
}

有人可以向我建议如何在装载图像时加入设置图像的想法吗?我的意思是当我尝试它时,图像的网址被完美取出。

我有一个list_item.xml,其中包含名称的textview和一个id为ImageView3的imageView。

谢谢:)

3 个答案:

答案 0 :(得分:0)

Picasso Library。它处理异步图像提取,淡入淡出动画,缓存,并且非常易于使用。

答案 1 :(得分:0)

正如约翰建议的那样,使用Picasso Library。您需要将图像URL绑定到适配器的getview方法中的imageview。

同样在你的onPostExecute方法中,你不需要在runonuithread方法中编写代码,因为onPostExecute方法本身在ui线程上运行。

答案 2 :(得分:0)

在Java中使用对象的良好做法首先使用以下代码创建一个名为UserBook的新类:

public class UserBook {

private String name;
private String BName;
private String imageUrl;

public UserBook() {
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getBName() {
    return BName;
}

public void setBName(String BName) {
    this.BName = BName;
}

public String getImageUrl() {
    return imageUrl;
}

public void setImageUrl(String imageUrl) {
    this.imageUrl = imageUrl;
}
}

现在列表活动中的ArrayList就像这样启动它:

private ArrayList<UserBook> userBooksList;

要填充我们的arraylist很简单,只需创建一个新的UserBook对象并将其放入我们的数组中:

    UserBook book = new UserBook();

    book.setName(Name);
    book.setBName(bName);
    book.getImageUrl(b_img);

    userBookList.add(book);

创建一个新的XML布局文件并将其命名为单元格。这将是我们的自定义单元格,我们的适配器将用于在列表视图中显示数据。

<?xml version="1.0" encoding="utf-8"?>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/cell_imageView" />

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/cell_textView" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:id="@+id/cell_textView2" />
</LinearLayout>

所以这里是最重要的部分,我们的listview自定义适配器。创建一个新的类名MyCustomAdapter:

public class MyCustomAdapter extends ArrayAdapter<UserBook> {

Context context;

public MyCustomAdapter(Context context, int resource, ArrayList<UserBook> books) {
    super(context, resource, books);

  //UPDATE!!!!
  this.context = context;

}


@Override
public View getView(int position, View cell, ViewGroup parent) {

    Holder holder;

    //First we check if the cell is being created for the first time, if its the case we inflate from
    //our xml

    if (cell == null){

        holder = new Holder();

        //get the xml inflator service
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        //Fill our cell with the xml
        cell = inflater.inflate(R.layout.cell, null);

        //Fill our holder with components
        holder.imageView = (ImageView)cell.findViewById(R.id.cell_imageView);
        holder.textView = (TextView)cell.findViewById(R.id.cell_textView);
        holder.textView2 = (TextView)cell.findViewById(R.id.cell_textView2);

        //this is very important..here we are attaching the holder to the current row
        cell.setTag(holder);
    }else{

        //the cell was created before so we can grab the holder attached
        holder = (Holder)cell.getTag();
    }

    //get current book item
    UserBook book = getItem(position);

    //fill data
    holder.textView.setText(book.getName());
    holder.textView2.setText(book.getBName());

    //set picasso
    Picasso.with(context).load(Uri.parse(book.getImageUrl())).into(holder.imageView);

    return cell;
}

//The holder will hold the inflated views and attach them to the listview's row
//for performance
private class Holder{

    ImageView imageView;
    TextView textView;
    TextView textView2;

}

}

简单地使用我们的自定义适配器:

 MyCustomAdapter adapter = new MyCustomAdapter(context, R.layout.cell, userBookList);

    listView.setAdapter(adapter);

请研究这个,我可以获得帮助,因为这是Android中处理列表视图的最佳做法