Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)

本文旨在对Android基础项目,ListView项目实际小应用(更多的结合小版块完成对用户需求的完整代码体现)

                                首先在这里,说说CSDN这个平台...

相信大家一定也不陌生,个人之前在学习中遇到的各种疑惑问题,无疑就是度娘一下,然后显而易见的就看到了页面靠前的CSDN,当然,csdn的seo是没的说的,Google也好,百度也罢,自己的文章发上去相对其他技术博客简书,博客园,知乎专栏,Github Page,当然还有很多个人建站的包括很多在这就不多说了,对于追求阅读量的作者会更有动力写,再而言之,在搜索质量上CSDN中相对来说更多的能解决很多实际应用中的基础问题等等,阅读量相对来说高一些,笔者不算是CSDN的长期用户,但也多多少少看到过不少大牛的博客,在这也不多言了,这篇博客是csdn首次编写,希望写一些基础性的更具清晰简洁的小项目,一方面帮助自己更深的理解记忆,一方面帮助有需求的同学解决一些具有相同疑惑的问题。

相关按钮涉及到布局方面的UI控件操作,强迫症暂且忽略,因时间问题,只做了简单调整,大家可以自行设置。

 

 

具体需求分析:

主需求 

1.利用ListView进行简单的结合(json解析数据完成网络请求显示到列表控件上)

2.点击按钮进行简单WebView的实现

次需求

1.初始页面广告倒计时5秒,结束后实现页面跳转,点击跳过可直接跳转至登录注册界面

2.登录注册界面,实现记住密码和自动登录功能

2.点击登录按钮判断注册信息是否与登录信息一致,点击注册按钮对用户名密码进行简单逻辑判断并保存到本地

3.登陆成功将解析的json数据显示到ListView上,完成列表界面并优化。

4.长按item条目点击事件进行删除操作,普通点击item点击事件进行修改操作,新的界面点击修改方可编辑数据,确定按钮实现对数据的回传

5.百度一下按钮实现简单的WebView跳转

 

简单演示图例(部分)
Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第1张图片Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第2张图片Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第3张图片

 

 

Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第4张图片Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第5张图片Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第6张图片

 

 

 

 

Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第7张图片Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第8张图片Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例)_第9张图片

 

附上最简单清晰的代码...初学者清晰易懂,

 

MainActivity(广告倒计时以及跳转操作)

package com.example.andprime;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
	int i = 6;
	private Timer t;
	// 利用HandlerMessage消息处理机制,实现倒计时操作
	Handler h = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 1:
				if (i == 0) { // 倒计时结束,调用timer对象cancel方法,并跳转到登录注册界面
					t.cancel();
					Intent intent = new Intent(MainActivity.this, TwoActivity.class);
					startActivity(intent);
				}
				tv2.setText("广告倒计时" + i + "秒");// 设置TextView控件文本

				break;

			default:
				break;
			}
		};
	};
	private TextView tv2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tv2 = (TextView) findViewById(R.id.tv2); // 倒计时文本控件
		findViewById(R.id.bttg).setOnClickListener(this); // Timertask的run方法具体的线程操作,每次减1,并调用handler对象发送

		t = new Timer();
		TimerTask task = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				i--;
				h.sendEmptyMessage(1);
			}

		};
		t.schedule(task, 1000, 1000); // 1秒后即执行,间隔1秒,
	}

	@Override
	// 点击跳过执行点击事件
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(MainActivity.this, TwoActivity.class);
		startActivity(intent); // 跳转至登录注册界面
	}
}

TwoActivity(记住密码自动登录以及登录判断)

package com.example.andprime;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class TwoActivity extends Activity implements OnClickListener {

	private EditText et2;
	private EditText et1;
	private CheckBox cb;
	private CheckBox cb2;
	private SharedPreferences sp2;
	private SharedPreferences sp;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_two);
		findViewById(R.id.login).setOnClickListener(this); // 登录按钮
		findViewById(R.id.regist).setOnClickListener(this); // 注册按钮
		cb = (CheckBox) findViewById(R.id.cb); // 多选记住密码
		cb2 = (CheckBox) findViewById(R.id.cb2); // 多选自动登录
		et1 = (EditText) findViewById(R.id.et1); // 用户名Edittext
		et2 = (EditText) findViewById(R.id.et2); // 密码Edittext
		sp2 = getSharedPreferences("userpass", MODE_PRIVATE); // 获取本地保存的文档userpass
		String name2 = sp2.getString("name", ""); // 获取注册的用户名
		String pass2 = sp2.getString("pass", ""); // 获取密码
		et1.setText(name2); // 设置到控件上
		et2.setText(pass2);
		sp = getSharedPreferences("rempass", MODE_PRIVATE); // 获取本地保存的文档rempass,记住密码
		boolean cb1 = sp.getBoolean("cb", false);
		boolean cb22 = sp.getBoolean("cb2", false);
		// 记住密码点击登录按钮前判断
		if (cb1) {
			String name = sp.getString("name", "");
			String pass = sp.getString("pass", "");
			et1.setText(name); // 记住用户名
			et2.setText(pass); // 记住密码
			cb.setChecked(true);// 设置勾选状态为true
		}
		// 自动登录点击登录按钮前判断
		if (cb22) {
			Intent intent = new Intent(TwoActivity.this, FourActivity.class);
			startActivity(intent);// 跳转
			cb2.setChecked(true);// 设置勾选状态为true
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.login: // 登录按钮
			// 记住密码点击登录按钮判断
			sp = getSharedPreferences("rempass", MODE_PRIVATE);
			Editor edit = sp.edit();
			boolean checked = cb.isChecked();
			boolean checked2 = cb2.isChecked();
			String sname = et1.getText().toString();
			String spaw = et2.getText().toString();
			if (checked) {

				// 保存 账号 和 密码
				edit.putString("name", sname);
				edit.putString("pass", spaw);
			}
			edit.putBoolean("cb", checked);
			edit.putBoolean("cb2", checked2);
			edit.commit();// 提交
			sp2 = getSharedPreferences("userpass", MODE_PRIVATE);
			String name2 = sp2.getString("name", "");
			String pass2 = sp2.getString("pass", "");
			// 判断登录的用户名和密码和注册信息是否一致
			if (!sname.equals(name2) || !spaw.equals(pass2)) {
				Toast.makeText(TwoActivity.this, "输入的数据有误,用户名密码与注册信息不一致", Toast.LENGTH_SHORT).show();
			} else {

				Intent intent = new Intent(TwoActivity.this, FourActivity.class);
				startActivity(intent);
			}
			break;

		case R.id.regist: // 注册按钮
			Intent intent = new Intent(TwoActivity.this, ThreeActivity.class);
			startActivity(intent);// 跳转至注册界面
			break;
		default:
			break;

		}
	}
}

ThreeActivity(注册界面)

package com.example.andprime;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;

public class ThreeActivity extends Activity implements OnClickListener {

	private EditText et1;
	private EditText et2;
	private EditText et3;

	@Override
	// 注册界面
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_three);
		findViewById(R.id.sure).setOnClickListener(this); // 确定注册按钮
		et1 = (EditText) findViewById(R.id.et1); // 注册用户名
		et2 = (EditText) findViewById(R.id.et2); // 注册密码
		et3 = (EditText) findViewById(R.id.et3); // 注册重复密码
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		String name = et1.getText().toString();
		String pass = et2.getText().toString();
		String pass1 = et3.getText().toString();

		// TODO Auto-generated method stub
		// 简单逻辑判断注册的用户名密码正则表达
		if (!name.matches("[a-zA-Z]{5,8}") || !pass.matches("[a-zA-Z]{5,8}") || !pass.equals(pass1)) {
			Toast.makeText(ThreeActivity.this, "数据有误", Toast.LENGTH_SHORT).show();
		} else {
			SharedPreferences sp = getSharedPreferences("userpass", MODE_PRIVATE);
			Editor edit = sp.edit();
			edit.putString("name", name);
			edit.putString("pass", pass);
			edit.commit();
			Intent intent = new Intent(ThreeActivity.this, TwoActivity.class);// 注册成功返回登录界面
			startActivity(intent);
		}
	}
}

FourActivity(网络请求解析设置适配器显示到ListView)

package com.example.andprime;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import com.google.gson.Gson;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

public class FourActivity extends Activity implements OnClickListener {
	int index1 = 0; // 长按条目位置索引变量
	private ListView lv; // Listview
	private ArrayList list;// json数据所用的集合
	private int index = 0; // 条目位置索引变量
	private MyAdapter adapter;// 适配器
	emo e = new emo(); // emo实例对象,json数据创建的对象

	// HandlerMessage处理机制,主线程的ui操作
	Handler h = new Handler() {

		public void handleMessage(android.os.Message msg) {
			String string = (String) msg.obj; // 得到Message发送过来的数据
			Gson gson = new Gson();
			Demo demo = gson.fromJson(string, Demo.class);// 简单Gson解析
			list = demo.getLol();
			adapter = new MyAdapter(list, FourActivity.this);// 适配器实例
			lv.setAdapter(adapter); // ListView设置适配器

			// 普通条目点击
			lv.setOnItemClickListener(new OnItemClickListener() {

				@Override
				public void onItemClick(AdapterView parent, View view, int position, long id) {
					// TODO Auto-generated method stub
					index = position;
					Intent intent = new Intent(FourActivity.this, FiveActivity.class);
					emo e = list.get(position);
					intent.putExtra("o", e);
					startActivityForResult(intent, 111);// 数据回传跳转至修改界面Five
				}
			});

			// 长按条目点击
			lv.setOnItemLongClickListener(new OnItemLongClickListener() {

				@Override
				public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {
					// TODO Auto-generated method stub
					index1 = position;
					new AlertDialog.Builder(FourActivity.this).setTitle("确定要删除吗")
							.setPositiveButton("确定", new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog, int which) {
									// TODO Auto-generated method stub
									list.remove(index1); // 长按确定进行删除操作
									adapter.notifyDataSetChanged(); // 对适配器进行刷新视图
								}
							}).setNegativeButton("取消", null).show(); // dialog的显示
					return true; // 长按条目返回的true操作
				}
			});
		};
	};

	// 具体的子线程耗时操作(Json数据网络请求)
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		final StringBuffer sb = new StringBuffer();
		setContentView(R.layout.activity_four);

		lv = (ListView) findViewById(R.id.lv);// Listview控件
		findViewById(R.id.baidu).setOnClickListener(this);// 百度一下按钮

		new Thread() {

			public void run() {
				try {
					URL url = new URL("http://192.168.1.111:1111/Exam17/test.json");// 此处为本机网络主机号,根据个人ip手动设置,目录为服务器默认文本
					HttpURLConnection open = (HttpURLConnection) url.openConnection();
					if (open.getResponseCode() == 200) {
						InputStream in = open.getInputStream();
						int len = 0;
						byte[] bys = new byte[1024];
						while ((len = in.read(bys)) != -1) {
							sb.append(new String(bys, 0, len)); // 读json数据
						}
					}
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Message msg = new Message();
				msg.obj = sb.toString();
				h.sendMessage(msg); // message对象将数据发送给主线程
			};
		}.start();
	}

	@Override
	// 回传过来的数据
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == 110) { // 结果码匹配
			emo o = (emo) data.getSerializableExtra("oo");// 得到回传的序列化对象
			list.set(index, o);// 修改当前位置的数据
			adapter.notifyDataSetChanged();
		} // 适配器刷新视图
	}

	@Override
	// 百度一下按钮点击事件
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(FourActivity.this, WebActivity.class);
		startActivity(intent);// 跳转至web
	}
}

 

MyAdapter实例(Convertview优化)

package com.example.andprime;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {
	ArrayList list;
	Context context;
	private TextView tv1;
	private TextView tv2;
	private TextView tv3;

	public MyAdapter(ArrayList list, Context context) { // 有参构造传过来的集合以及上下文Context
		super();
		this.list = list;
		this.context = context;
	}

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

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	// 适配器ConvertView优化
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		ViewHolder v = null;
		// 判断填充的是否为空
		if (convertView == null) {
			convertView = LayoutInflater.from(context).inflate(R.layout.item, null); // 得到自定义布局
			tv1 = (TextView) convertView.findViewById(R.id.tv1);
			tv2 = (TextView) convertView.findViewById(R.id.tv2);
			tv3 = (TextView) convertView.findViewById(R.id.tv3);
			v = new ViewHolder();
			v.tv1 = tv1;
			v.tv2 = tv2;
			v.tv3 = tv3;
			convertView.setTag(v); // 为空,具体优化
		} else {
			v = (ViewHolder) convertView.getTag(); // 非空直接取出
		}
		v.tv1.setText(list.get(position).getName());// 控件设置数据
		v.tv2.setText(list.get(position).getLocation());
		v.tv3.setText(list.get(position).getJob());
		return convertView;// 返回Convertview
	}

	// Viewholder实例对象
	class ViewHolder {
		TextView tv1;
		TextView tv2;
		TextView tv3;
	}

}

FiveActivity(普通点击事件跳转到的修改界面并回传数据)

package com.example.andprime;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;

public class FiveActivity extends Activity implements OnClickListener {

	private EditText et1;
	private EditText et2;
	private EditText et3;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_five);
		et1 = (EditText) findViewById(R.id.et1); // 设置修改的值1
		et2 = (EditText) findViewById(R.id.et2); // 设置修改的值2
		et3 = (EditText) findViewById(R.id.et3); // 设置修改的值3
		findViewById(R.id.sure).setOnClickListener(this); // 修改按钮
		findViewById(R.id.sureup).setOnClickListener(this);// 确定修改按钮
		Intent intent = getIntent();
		emo e = (emo) intent.getSerializableExtra("o");// 传过来的序列化对象
		et1.setText(e.getName()); // 显示到控件
		et2.setText(e.getLocation());
		et3.setText(e.getJob());
	}

	@Override
	// 按钮点击监听
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		// 修改按钮监听
		case R.id.sure:

			et1.setEnabled(true); // 将3个文本设置为可编辑状态
			et2.setEnabled(true);
			et3.setEnabled(true);
			break;
		// 确定修改按钮点击监听
		case R.id.sureup:

			String name = et1.getText().toString();
			String location = et2.getText().toString();
			String job = et3.getText().toString();
			Intent intent2 = getIntent();
			intent2.putExtra("oo", new emo(name, location, job));// 将修改后的数据通过序列化对象回传
			setResult(110, intent2);// 数据回传
			finish();
			;// 关闭本界面

			break;
		default:
			break;
		}
	}
}

 

WebActivity(读取百度页面)

package com.example.andprime;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;

public class WebActivity extends Activity {

	private WebView wv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_web);
		wv = (WebView) findViewById(R.id.wv);// webView控件
		wv.loadUrl("http://www.baidu.com");// 简单的跳转百度页面操作
	}

	@Override
	// 关闭多余的界面
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		finish();
	}
}

Json数据段示例

{
	"lol": [{
			"name": "寒冰",
			"location": "下路",
			"job": "射手"
		},
		{
			"name": "德玛",
			"location": "上路",
			"job": "坦克"
		},
		{
			"name": "寡妇",
			"location": "野区",
			"job": "打野"
		},
		{
			"name": "女神",
			"location": "下路",
			"job": "辅助"
		},
		{
			"name": "寒冰",
			"location": "下路",
			"job": "射手"
		}
	]
}

Gson解析json数据对应的两个具体实体类

package com.example.andprime;

import java.util.ArrayList;

public class Demo {
	ArrayList lol; 	//遇到数组创建的集合

	public ArrayList getLol() {
		return lol;
	}

	public void setLol(ArrayList lol) {
		this.lol = lol;
	}
	
}

 

package com.example.andprime;

import java.io.Serializable;

public class emo implements Serializable{
	private String name;	//与json数据一一对应
	private String location;
	private String job;
	public emo(String name, String location, String job) {
		super();
		this.name = name;
		this.location = location;
		this.job = job;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public emo() {
		super();
		// TODO Auto-generated constructor stub
	}
}

UI布局文件

MainActivity布局


       
	
    
    
        

TwoActivity布局

 



    
      
    

    
    
      
    


    
    
      
     

    

        

ThreeActivity布局

 


     

   
      
    

    
    
      
    

  
    
      
    

  
    

        

 

FourActivity布局


	
	    

 

FiveActivity布局



  
    >
     

 

WebActivity布局



    


 

 

Item自定义条目布局

 



    
     
    
     
	
	


    
	  
	
	

 

你可能感兴趣的:(Android中ListView结合网络请求开发小案例(适合初学者必看的一篇详细实例))