Android SwipeRefreshLayout 下拉刷新

Posted on Leave a commentPosted in Android

以前写下拉刷新 感觉好费劲,要判断ListView是否滚到顶部,还要加载头布局,还要控制 头布局的状态,等等一大堆。感觉麻烦死了。今天学习了SwipeRefreshLayout 的用法,来分享一下,有说的不对的地方请大家指点。

SwipeRefreshLayout 是Google在support v4 19.1版本的library更新的一个下拉刷新组件,也就是说 开发的时候把Android版本调到4.4或者以上才会有这个。

先来看看效果图

再来看看布局文件里的代码(我这里放的是一个ListView 当然也可以放其他控件 只要你高兴就好)

 <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/main_srl_bloglist"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <ListView
            android:id="@+id/main_lv_bolg_list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:divider="#00000000"
            android:dividerHeight="5dp"></ListView>

    </android.support.v4.widget.SwipeRefreshLayout>

最后来看看Activiy里的代码吧(这里我用的AndroidAnnotations 所以没有写 findViewById 哈哈)

 //设置刷新时动画的颜色,可以设置4个
        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mIndex=1;
                mBlogList.clear();
                loadBlogData();
            }
        });

在onRefresh 里调用获取数据的方法就好了 数据获取完毕 别忘了 修改状态

mSwipeRefreshLayout.setRefreshing(false);

哈哈 以前要写成吨的代码 用SwipeRefreshLayout 就这几行代码 是不是很方便。

Android通过Volley请求WebApi共通

Posted on Leave a commentPosted in Android

思路:

1.把请求网络的方法放到一个类里面

2.创建一个接口将数据发给Activity

3.Activity 实现接口获得服务器返回的数据

4.解析数据

 

来我们一先来看第一步

请求网络

在这里请求网络我们用Volley 。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。当然Volley对加载图片的时候内存控制的很好,后面加载图片还会用到。

创建一个CallWebservice 类

package org.shuaibi.hi_blog.utils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.json.JSONObject;

import android.content.Context;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

public class CallWebservice  {

    private final String HTTPHOST="http://blog.haojima.net/api/home/";  //主机地址
    public static RequestQueue requestQueue;
    private Context mContnxt; 
    private int mMark;
    private ServiceCallBack mServiceCallBack; 

    public CallWebservice(Context context,String function,HashMap&lt;String, String&gt; params,int mark)
    {
        this.mContnxt=context;
        this.mMark=mark;
        this.mServiceCallBack=(ServiceCallBack) context;
        createUrl(function,params);
    }

    public void createUrl(String function,HashMap&lt;String, String&gt; params)
    {
        //拼主机名和方法名

        String url=this.HTTPHOST+function;
        //拼参数

        if(params!=null){
            url+="?";
            Iterator&lt;Entry&lt;String, String&gt;&gt; iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry&lt;String, String&gt; obj = (Entry&lt;String, String&gt;) iterator.next();
                url+=obj.getKey().toString()+"="+obj.getValue().toString()+"&amp;";
            }
            url=url.substring(0, url.length()-1); //去掉最后一个 &amp;
        }
        //请求服务器

        getJsonResult(url);

    }

    public void getJsonResult(String url)
    {
        if(CallWebservice.requestQueue==null)
        {
            requestQueue=Volley.newRequestQueue(mContnxt);
        }
        JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(url, null, new Listener&lt;JSONObject&gt;() {
            @Override
            public void onResponse(JSONObject response) {
                mServiceCallBack.serviceResult(response, mMark);
            }
        }, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
             Toast.makeText(mContnxt, error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
        requestQueue.add(jsonObjectRequest);
    }
}

下面来写接口

package org.shuaibi.hi_blog.utils;

import org.json.JSONObject;

/**

 * 

 * @描述: 服务器返回值回调

 * @作者: ZeroX

 * @时间: 2015-9-16

 * @参数: 

 * @接口: 

 *

 */
public interface ServiceCallBack {
    void serviceResult(JSONObject jsonObject,int mark);
}

看见了接口的代码很简单就几句话, 里面的jsonObject 就是服务器返回值 mark 是标记当一个Activity里有多个请求网络的地方 我们就可以用mark 区分哈哈 。

这样请求网络就算完成了,下面介绍用法

HashMap<String, String> params=new HashMap<String, String>();
        params.put("idex",mIndex+"");
        params.put("sizePage", mPageSize+"");
        params.put("ContentLength", "80");
        new CallWebservice(this,"get",params,GETBLOGLIST);

上面代码就是调用一个 方法的写法  里面的GETBLOGLIST 是定义的一个常量我写的1,用来区分多个网络请求的这个数就是 上面接口里的mark

最后就是Activity实现 ServiceCallBack 这个接口了 实现一下serviceResult 这个方法

public class MainActivity extends Activity implements ServiceCallBack
@Override
    public void serviceResult(JSONObject jsonObject, int mark) {
        try {
            switch (mark) {
            case GETBLOGLIST:
                 blogResultHander(jsonObject.getJSONArray("blog"));
mPageCount=jsonObject.getInt("total");
                break;
            default:
                break;
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
        }

    }

最后就是解析Json了

 /**

     * 博客列表返回值处理

     * @param jsonArray 博客列表

     */
    public void blogResultHander(JSONArray jsonArray) throws Exception
    {
        for (int i = 0; i &lt; jsonArray.length(); i++) {
            JSONObject jsonObject=jsonArray.getJSONObject(i);
            HashMap&lt;String, String&gt; itemHashMap=new HashMap&lt;String, String&gt;();
            itemHashMap.put("UserName", jsonObject.getJSONObject("BlogUsersSet").getString("UserNickname"));
            itemHashMap.put("CreateTime", jsonObject.getString("BlogCreateTime"));
            itemHashMap.put("Title", jsonObject.getString("BlogTitle"));
            itemHashMap.put("Content", jsonObject.getString("BlogContent"));
            itemHashMap.put("Comment", jsonObject.getString("BlogCommentNum"));
            itemHashMap.put("Visibility", jsonObject.getString("BlogReadNum"));
            mBlogList.add(itemHashMap); //这是一个List&lt;HashMap&lt;String,String&gt;&gt;
        }

    

    }

哈哈我们已经把 重服务器返回的数据放到List里了。

上面代码只是提共参考哟 完整代码请点击这里 

Android Studio配置 AndroidAnnotations

Posted on Leave a commentPosted in Android

以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置。

AndroidAnnotations是一个能够让你快速进行Android开发的开源框架,它能让你专注于真正重要的地方。使代码更加精简,使项目更加容易维护,它的目标就是“Fast Android Development.Easy maintainance”。 说白了 就是可以少写很多代码,哈哈。

AndroidAnnotations是一个开源项目 项目地址 有兴趣的朋友可以去研究一下。好了 废话不多说了。

1 我们需要把 AndroidAnnotations下载下来

2 新建文件夹 compile-libs

3 将androidannotations-3.2.jar 复制到 compile-libs 将 androidannotations-api-3.2.jar 复制到libs下

如:

4 在项目的build.gradle 添加 classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.4’

如:

5 在Model 的build.gradle  添加

5.1 apply plugin: ‘android-apt’

def AAVersion = ‘3.2+’

5.2  apt “org.androidannotations:androidannotations:$AAVersion”
compile “org.androidannotations:androidannotations-api:$AAVersion”
compile ‘com.android.support:support-v4:22.1.1’

5.3 apt {

arguments {

androidManifestFile variant.outputs[0].processResources.manifestFile

resourcePackageName ‘org.shuaibi.hi_blog’

}

}

如:

到这里配置就算完成了 下面来看一下 怎么使用

package org.shuaibi.hi_blog.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import org.shuaibi.hi_blog.R;

@EActivity(R.layout.activity_main)  //指定视图
public class MainActivity extends Activity {

    @ViewById(R.id.main_tv_hello)
    TextView mHelloWord; //绑定控件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Click(R.id.main_tv_hello) //点击事件按
    public void hello_Click() {
        Intent intent = new Intent(this, BlogDetailActivity_.class);
        startActivity(intent);
    }


    @AfterViews //视图加载完毕后执行
    public void init() {

        Toast.makeText(this, "视图加载完毕", Toast.LENGTH_SHORT).show();

    }

}

最后 要在 AndroidManifest 文件中 给Activity加上 _ (这是一个下横杠)

如果要在 Eclipse 中配置请 移步到这里–> 传送

对Android Studio 不是很熟 有什么不对的地方请多多指教

Android万能的Adapter

Posted on Leave a commentPosted in Android

啊哈,今天来分享一个万能AndroidAdapter,想提高工作效率,和懒的程序猿同胞们有福了,嘻嘻。
代码很简单就不做解释了 直接上代码
先来个CommonAdapter继承BaseAdapter


package org.shuaibi.androidexplore.utils;

import java.util.List;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

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

/**
*
* @描述: CommonAdapter
* @作者: ZeroX
* @时间: 2015-8-30
* @参数:
* @接口:
*
*/
public abstract class CommonAdapter<T> extends BaseAdapter {

protected List<T> mList;
protected Context mContext;
protected RequestQueue mQueue;
protected ImageLoader mImageLoader;

public CommonAdapter(){

}
public CommonAdapter(List<T> list,Context context)
{
this.mList=list;
this.mContext=context;
this.mQueue = Volley.newRequestQueue(context);
this.mImageLoader = new ImageLoader(mQueue, new BitmapCache());
}

@Override
public int getCount() {

return mList.size();
}

@Override
public Object getItem(int position) {
return mList.get(position);
}

@Override
public long getItemId(int position) {

return position;
}

@Override
public abstract View getView(int position, View convertView, ViewGroup parent);

}

&nbsp;

&nbsp;

 

然后是ViewHolder 这是重点

 


package org.shuaibi.androidexplore.utils;

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
*
* @描述: ViewHolder
* @作者: ZeroX
* @时间: 2015-8-30
* @参数:
* @接口:
*
*/
public class ViewHolder {

private SparseArray<View> mView;
private View mConvertView;
public int mPosition;

public ViewHolder(Context context,ViewGroup parent,int position,int layoutId)
{
mView=new SparseArray<View>();
mPosition=position;
mConvertView=LayoutInflater.from(context).inflate(layoutId, parent,false);
mConvertView.setTag(this);
}

public    ViewHolder ()
{

}
public static ViewHolder get(Context context,View convertView,ViewGroup parent,int position,int layoutId)
{
if(convertView==null)
{
return new ViewHolder(context, parent, position, layoutId);
}else {
ViewHolder viewHolder=(ViewHolder) convertView.getTag();
viewHolder.mPosition=position;
return viewHolder;
}

}

@SuppressWarnings("unchecked")
public<T extends View> T getView(int viewId)
{
View view=mView.get(viewId);
if(view==null)
{
view=mConvertView.findViewById(viewId);
mView.put(viewId, view);
}
return (T) view;

}

public View getConvertView()
{
return mConvertView;
}

}

下面是使用方法


package org.shuaibi.androidexplore.adapter;

import java.util.HashMap;
import java.util.List;

import org.shuaibi.androidexplore.R;
import org.shuaibi.androidexplore.config.Config;
import org.shuaibi.androidexplore.utils.CommonAdapter;
import org.shuaibi.androidexplore.utils.ViewHolder;
import com.android.volley.toolbox.NetworkImageView;

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

/**
*
* @描述: 产品列表适配器
* @作者: ZeroX
* @时间: 2015-8-30
* @参数:
* @接口:
*
*/
public class ProductListAdapter extends CommonAdapter<HashMap<String, String>> {

public ProductListAdapter(List<HashMap<String, String>> list,Context context)
{
super(list,context);
}

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

ViewHolder holder=ViewHolder.get(mContext, convertView, parent, position,R.layout.item_main);

HashMap<String, String> dataHashMap=(HashMap<String, String>) mList.get(position);
((TextView)holder.getView(R.id.main_tv_productName)).setText(dataHashMap.get("ProductName"));
((NetworkImageView)holder.getView(R.id.main_iv_productimg)).setImageUrl(Config.FILE_ADDRESS+dataHashMap.get("ImageUrl"),mImageLoader);

return holder.getConvertView();
}

}

看是不是比以前少写了很多代码。有不明白的地方 可以去这里看视频

 

 

Android通过Soap请求Webservice共通

Posted on Leave a commentPosted in Android

好久都没写了,今天总结的是Android中通过Soap协议访问Webservice共通类。
首先下载一个第三方jar包k2soap-android-timeout.jar 将下载的文件 放到libs 文件夹下。
实现思路
新建一个接口ServiceCallBack用来传递数据

package org.shuaibi.exploration.utils;

import org.json.JSONObject;

/**
 *
 * @author ZeroX
 *
 */
public interface ServiceCallBack {
	/**
	 * 接口返回值
	 * @param jsonObject 返回的json
	 * @param mark 调用接口时传的标识
	 */
	public void ServiceResult(JSONObject jsonObject,int mark);
}

新建CallWebservice类继承Thread 在线程里面请求网络,然后后将返回的数据发给主线程,最后通过ServiceCallBack发送给Activity ,再在Activity 里处理返回的数据 废话不多说 直接上代码

package org.shuaibi.exploration.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;
import org.json.JSONObject;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;


import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.widget.Toast;



@SuppressLint("HandlerLeak")
public class CallWebServiceBySoap extends Thread{
	private String method,httphost;
	private HashMap<String, String> params;
	private Context context;
	private ServiceCallBack serviceCallBack;
	private int mark;

	/**
	 * Activity访问WebService
	 * @param context 上下文 一定要传 this
	 * @param method 方法名称
	 * @param params 参数名称 
	 * @param serviceName service名
	 * @param mark 标记
	 */
	public CallWebServiceBySoap(Context context,String method, HashMap<String, String> params, String httpHost,int mark)
	{
		this.method=method;
		this.params=params;
		this.httphost=httpHost;
		this.context=context;
		this.serviceCallBack=(ServiceCallBack) context;
		this.mark=mark;
	}

	/**
	 * Fragment访问WebService
	 * @param context 上下文 一定要传 this
	 * @param method 方法名称
	 * @param params 参数名称 
	 * @param serviceName service名
	 * @param mark 标记
	 */
	public CallWebServiceBySoap(Fragment fragment,String method, HashMap<String, String> params, String httpHost,int mark)
	{
		this.method=method;
		this.params=params;
		this.httphost=httpHost;
		this.context=fragment.getActivity();
		this.serviceCallBack=(ServiceCallBack) fragment;
		this.mark=mark;
	}

	@Override
	public void run() {
		super.run();
		Message message=new Message();
		try {
			message.what=1;

			message.obj=getJSONObject(method,params,httphost);
		}catch(ConnectTimeoutException e){
			message.what=-5;
			e.printStackTrace();

		}catch (IOException e) {
			message.what=-5;

			e.printStackTrace();
		}catch (XmlPullParserException e) {

			message.what=-6;
			e.printStackTrace();
		} catch (JSONException e) {

			message.what=-7;
			e.printStackTrace();
		}
		resuleHandler.sendMessage(message);
	}


	Handler resuleHandler=new Handler()
	{
		public void handleMessage(android.os.Message msg) {
			try {

				switch(msg.what)
				{
				case 1:
					int result=((JSONObject)msg.obj).getInt("result");
					switch(result){
					case 1: //状态为1将数据 发到Activity处理
						serviceCallBack.ServiceResult((JSONObject)msg.obj, mark);
						break;
					default ://其他状态 弹出提示信息
						Toast.makeText(context,((JSONObject)msg.obj).getString("msg"), Toast.LENGTH_SHORT).show();
						break;
					}

					break;
				case -5:
					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context,"连接服务器失败,请检查网络!", Toast.LENGTH_SHORT).show();
					}
					break;
				case -6:
					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context,"数据解析异常,请稍后再试!", Toast.LENGTH_SHORT).show();
					}
					break;
				case -7: 
					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context,"返回数据异常!", Toast.LENGTH_SHORT).show();
					}
					break;
				default:

					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context, "连接服务器失败,请检查网络", Toast.LENGTH_SHORT).show();
					}
					break;
				}
			} catch (JSONException e) {
				Toast.makeText(context, "数据处理异常,请稍后再试", Toast.LENGTH_SHORT).show();
				e.printStackTrace();
			}
		};
	};

	public static JSONObject getJSONObject(String method, HashMap<String, String> params, String httphost) throws IOException, XmlPullParserException, JSONException  {
		String wsdlURL = "http://" + Config.WEBSERVICE_IP + httphost;
		String webMethod = method;
		String namespace = Config.NAME_SPACE;
		String soapAction = namespace + webMethod;
		// 步骤2 创建一个SoapObject对象
		SoapObject soapObject = new SoapObject(namespace, webMethod);
		if(params!=null){
			// 步骤3 传递参数
			Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
			// 循环读取 传递参数
			while (iterator.hasNext()) {
				Entry<String, String> obj = (Entry<String, String>) iterator.next();
				// 将参数添加到SoapObject对象中
				soapObject.addProperty(obj.getKey().toString(), obj.getValue().toString());
			}
		}
		// 步骤4 创建SoapSerializationEnvelope
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.dotNet = true;
		// 步骤5 设置一下传回对象
		envelope.bodyOut = soapObject;
		envelope.setOutputSoapObject(soapObject);
		// 步骤6 创建HttpTransportSE用于传输对象
		HttpTransportSE se = new HttpTransportSE(wsdlURL, 1000 * 10);
		JSONObject jsonObject = null;
		se.call(soapAction, envelope);
		// 步骤8获取从webService返回的结果
		if (envelope.getResponse() != null) {
			jsonObject = new JSONObject(envelope.getResponse().toString());
			Config.NETWORKNUM=0;
		}
		return jsonObject;
	}



}

 

使用方法


package org.shuaibi.exploration.activity;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import org.json.JSONObject;
import org.shuaibi.exploration.R;
import org.shuaibi.exploration.utils.CallWebServiceByPost;
import org.shuaibi.exploration.utils.ServiceCallBack;

import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;
/**
 *
 * @author ZeroX
 *
 */
@EActivity(R.layout.activity_main)
public class MainActivity extends Activity implements ServiceCallBack {

	private final int GETIMG=1;
	private int num=10;

	@ViewById(R.id.tv_result)
	public TextView tv_result;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@AfterViews
	public void initData()
	{
		//请求WebService
		new CallWebServiceByPost(this, "meinv?num="+num, null, GETIMG).start();
	}

	@Override
	public void ServiceResult(JSONObject jsonObject, int mark) {
		switch (mark) {
		case GETIMG:
			//处理接口返回值
			tv_result.setText(jsonObject.toString());
			break;

		default:
			break;
		}

	}

}

AndroidAnnotaions框架使用

Posted on Leave a commentPosted in Android
转眼干Android 也有一些日子了。平时在工作中findViewById和setOnClickListener像这些都是经常写的。一个项目下来,这样的语句会写一大堆。感觉这样的语句写多少遍都不会有什么高。那么问题来了,我们可不可以不写这写语句,答案是坑定的,当然可以。
现在就来介绍我们今天的主角AndroidAnnotaions,这个框架是一个开源框架,大家可以以在GitHub上找到它,这次我们只讨论怎么使用 ,所以就直接下载jar 包 来用。

解压文件能看见两个jar 包

androidannotations-api-3.2.jar
androidannotations-3.2.jar
把androidannotations-api-3.2.jar放到libs 文件夹下
然后在项目中新建一个 文件夹 compile-lib 把下载的androidannotations-3.2.jar放到该文件夹下
右键项目 Build Path -> Configur Build Path ->Java Compiler -> Annotation Processin -> Enable projecr specific settings 打上对号 -> Factory Path ->Add Jars 找到放到 compile-lib 里面的 androidannotations-3.2.jar -> apply
完成上面配置后现在就来 开始使用吧
package org.shuaibi.androidannotions;

import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;

import com.example.androidannotions.R;

import android.os.Bundle;
import android.app.Activity;
import android.widget.Button;
import android.widget.TextView;

@EActivity(R.layout.activity_main) //设置页面视图
public class MainActivity extends Activity {

@ViewById(R.id.btn_main_clickme)  //找id为btn_main_clickme的Button 相当于findViewById
Button mClickMe;
@ViewById(R.id.tv_main_helloword)
TextView mHelloWord;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Click(R.id.btn_main_clickme) //给id为btn_main_clickme的Button 设置点击事件
void myButton()
{
mHelloWord.setText("点了我一下");

}

}
上面代码只是简单介绍了AndroidAnnotations 的基本用法。更多用法请参见官方文档