从网络端leanCloud获取上传的图片和文字并以listview的形式显示在android端

来源:互联网 发布:数据库管理系统access 编辑:程序博客网 时间:2024/05/17 07:27

博主刚接触android,对android理解还很粗浅,研究listview的不足之处还请包涵,研究listview显示网络资源2、3个星期终有些心得在此和大家分享一下。不会使用leancloud的先自己看看入门案例吧。废话不多说上代码:


MyListView.java

每个item要显示的不多就3个控件1个imageview,2个textview,所以创建了一个类来封装一下。

四个属性

private String imageView;
private String textView1;
private String textView2;
private String imageName;//图片名称,因为待会要从服务器获取图片保存到本地目录,有一个名字还是必须的

添加set、get方法以及初始化方法,这就不用我介绍了吧,右击空白地区选择source里面都有的。


ViewWrapper.java

这个类主要是获取List<MyList>的对象lists,并连接layout_item中获取id,以及渲染对应位置的view

private List<MyList> listViews;

private ImageView imageView1;
private TextView textView1;
private TextView textView2;


public ViewWrapper(View baseView,List<MyList> lists){
this.listViews = lists;

imageView1 = (ImageView) baseView.findViewById(R.id.imageView1);
textView1 = (TextView) baseView.findViewById(R.id.textView1);
textView2 = (TextView) baseView.findViewById(R.id.textView2);
}

public void drawListItem(int position) {
MyList myList = listViews.get(position);


imageView1.setImageBitmap( BitmapFactory.decodeFile(myList.getImageView())); 
textView1.setText(myList.getTextView1());
textView2.setText(myList.getTextView2());

}


MyAdapter.java

这个类就是自己继承ArrayAdapter写的适配器,listView与数据集必须有adapter,adapter我也不是太懂,此处只简单介绍ArrayAdapter的使用

public class MyAdapter extends ArrayAdapter<MyList>{
private List<MyList> lists;

public MyAdapter(Context context, List<MyList> lists) {
super(context, R.layout.layout_list, lists);


this.lists = lists;
}

@Override
public int
getCount() {
// TODO Auto-generated method stub
return lists.size();
}

@Override
public View
getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewWrapper viewWrapper = null;


if (row == null) {
LayoutInflater inflater = (LayoutInflater) MainActivity.getInstance().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);//获取Inflator有三种方法,自查吧。。。


row = inflater.inflate(R.layout.layout_list, parent, false);
viewWrapper = new ViewWrapper(row, lists);
row.setTag(viewWrapper);
} else {
viewWrapper = (ViewWrapper) row.getTag();
}


viewWrapper.drawListItem(position);
return row;
}
}

最后是MainActivity.java

这里面涉及的就有点多了最关键是线程的使用以及message、handler的使用本人对此所知浅薄就不深入解析了

public class MainActivity extends ActionBarActivity implements OnItemClickListener{


private static MainActivity instance;

private final String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
private final String path = "Rest";

private static int nSize = 0;
private Handler myHandler;
private List<MyList> lists = new ArrayList<MyList>();
private ListView lv;
private MyAdapter adapter1;

public static MainActivity getInstance()
{
return instance;
}

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

instance = this;

lv = (ListView) findViewById(R.id.listView1);
adapter1 = new MyAdapter(this, lists);
lv.setAdapter(adapter1);
lv.setOnItemClickListener(this);

getThread().start();

myHandler = new Handler() {  
         public void handleMessage(Message msg) {   
              switch (msg.what) {
                   case 1:   
                   adapter1.notifyDataSetChanged();//这就是用来在接收消息后刷新listView显示用的,个人感觉就像回调一样。
                        break; 
              }
              super.handleMessage(msg);   
         }   
    };

}

private Thread getThread()
{
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("https://api.leancloud.cn/1.1/classes/MyClass");//只需修改MyClass为自己的类即可,这个类在LeanCloud的存储界面创建
httpGet.setHeader("Content-Type", "application/json");
httpGet.setHeader("X-AVOSCloud-Application-Id",
"XXXXXXXXXXXXXXXXXXX-XXXXXXXX");//此处填写LeanCloud创建应用后获得的App-ID
httpGet.setHeader("X-AVOSCloud-Application-Key",
"XXXXXXXXXXXXXXXXXXXXXX");//此处填写LeanCloud创建应用后获得的App-Key


try {
HttpResponse response = client.execute(httpGet);

if(response.getStatusLine().getStatusCode() == 200)  
           {
               HttpEntity httpEntity = response.getEntity();  
               String result = EntityUtils.toString(httpEntity);//取出应答字符串
try {
JSONObject jo = new JSONObject(result);
JSONArray jsonArray = jo.getJSONArray("results");
nSize = jsonArray.length();
for (int i = 0;i < nSize;++i) {
JSONObject jsonpet = jsonArray.getJSONObject(i);
final String str1 = jsonpet.getString("url");
final String str2 = jsonpet.getString("name");
final String str3 = jsonpet.getString("introduce");
final String str4 = jsonpet.getString("imageName");//获取自己表中的字段,随意定义通过LeanCLoud的Rest Api的在线测试工具可以上传信息。图片文件的话,我是在应用的发布消息出上传的,会保存到_File表里并生成一个url,获取到这个url后在android端想获取图片也难度不大。

new Thread(){  
                   public void run() {
                       try {  
                           URL url = new URL(str1);
                           HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
                           conn.setConnectTimeout(6*1000); 
                           if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");  
                           InputStream inSream = conn.getInputStream();  
                           //把图片保存到项目的根目录
                           File f = new File(rootPath+"/"+path);
                           if(!f.exists()){
                           f.mkdirs();
                           }
                           readAsFile(inSream, new File(rootPath+"/"+path+"/"+str4));  
                       } catch (Exception e) {  
                           e.printStackTrace();  
                       }
                   };
               }.start();

MyList mylist = new MyList();
mylist.setImageView(rootPath+"/"+path+"/"+str4);
mylist.setTextView1(str2);
mylist.setTextView2(str3);
lists.add(mylist);

Message message = new Message();
message.what=1;
myHandler.sendMessage(message);
try {
Thread.sleep(400);//这个时间很重要,我写200就刷不出来,因为获取资源要时间,所以刷新适配器要等一会。
} catch (InterruptedException e) {
Thread.currentThread().interrupt();   
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
           } 
else   
                    httpGet.abort();  
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

});
return thread;
}

public static void readAsFile(InputStream inSream, File file) throws Exception{  
       FileOutputStream outStream = new FileOutputStream(file);  
       byte[] buffer = new byte[1024];  
       int len = -1;  
       while( (len = inSream.read(buffer)) != -1 ){  
           outStream.write(buffer, 0, len);  
       }  
       outStream.close();  
       inSream.close();  
   }

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
Intent intent = new Intent("android.intent.action.VIEW", Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
 
 
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

顺便附上用到的layout

activity_main.xml

布局随意吧,我用的是相对布局,里面只有一个控件

<ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true" >

</ListView>

layout_list.xml

此处相对布局较简单

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="18dp"
        android:layout_marginTop="20dp"
        android:src="@drawable/ic_launcher" />


    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imageView1"
        android:layout_alignLeft="@+id/textView1"
        android:text="TextView" />


    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/imageView1"
        android:layout_marginLeft="22dp"
        android:layout_toRightOf="@+id/imageView1"
        android:text="TextView" />

</RelativeLayout>

好了,到此结束,新手可以参考参考,老死机也请多多指教

1 0