最近做了一个关于电话归宿地和IP归属地查询的小应用,记录分享一下主要的过程。
1、简介
数据来源是使用的聚合数据的免费api接口。
2、整体外层结构
由上可知整体功能为IP查询和电话归宿地查询,外层结构由底部的导航栏,主体部分是利用Viewpager来装载了两个Fragment。然后整体使用了模仿沉浸式效果
1)MainActivity
沉浸式设置代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT>=21){ //只有5.0及以上系统才支持,因此这里先进行了一层if判断
View decorView=getWindow().getDecorView();
int option= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE //注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;//表示会让应用的主体内容占用系统导航栏的空间
decorView.setSystemUiVisibility(option);//设置
getWindow().setStatusBarColor(Color.TRANSPARENT);//设置状态栏透明
fragmentAdapter=new FragmentAdapter(getSupportFragmentManager());
bindView();
}
}
底部导航栏是用一个RadioGroup装载两个RadioButton:
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.rb_phone:
mViewPager.setCurrentItem(PAGE_ONE);
break;
case R.id.rb_ip:
mViewPager.setCurrentItem(PAGE_TWO);
break;
}
}
然后为Viewpager设置当前页面:
private ViewPager mViewPager;
//几个代表页面的静态常量
public static final int PAGE_ONE=0;
public static final int PAGE_TWO=1;
private FragmentAdapter fragmentAdapter;
@Override
public void onPageScrollStateChanged(int state) {
//state的状态有三个,0表示什么都没做,1正在滑动,2滑动完毕
if (state==2){
switch (mViewPager.getCurrentItem()){
case PAGE_ONE:
rb_phone.setChecked(true);
break;
case PAGE_TWO:
rb_ip.setChecked(true);
break;
}
}
}
2)FragmentAdapter
public class FragmentAdapter extends FragmentPagerAdapter {
private FragmentPhone fgPhone;
private FragmentIp fgIp;
//定义页面的静态常量
private static final int PAGE_ONE=0;
private static final int PAGE_TWO=1;
private final static int FragmentCount=2;
public FragmentAdapter(FragmentManager fm) {
super(fm);
fgPhone=new FragmentPhone();
fgIp=new FragmentIp();
}
@Override
public Fragment getItem(int position) {
Fragment fragment=null;
switch (position){
case PAGE_ONE:
fragment=fgPhone;
break;
case PAGE_TWO:
fragment=fgIp;
break;
}
return fragment;
}
@Override
public int getCount() {
return FragmentCount;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println("position Destory" + position);
super.destroyItem(container, position, object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
}
3、具体查询Fragment代码
网络数据请求我这里引用了xUtils框架,为了学习新知识又用了okhttp来实现。之后还想用retrofit来实现一下。
这里主要分析使用okhttp时候遇到的代码和问题。
注意使用okhttp的I/O操作是基于Okio的,还有就是在使用网路请求操作时不能在主线程做耗时操作,okhttp提供了异步请求方法,但是在使用了该方法的时候如果需要做UI更新操作一定要切换到主线程中进行。这里贴出主要的请求方法:
private void QueryP(String phone) throws Exception{
String url="http://apis.juhe.cn/mobile/get?phone="+phone+"&key=ea4ad65571faff477a1a7c66b9a58f42";
Request request=new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
/*
* 填坑=.= 我们在调试的时候喜欢Log一下看看数据正不正常,我在使用HttpURLConnection
* 或者 HttpClient 获取Response时都是先Log看看然后再传输给其他函数去解析,
* 没有出现这样的问题;但是在使用OKhttp时就不正常了,因为调用了一次response.body().string(),那么这个流就已经被关闭了*/
String responseInfo=response.body().string();
Log.i(TAG, "onResponse:Okhttp return result= "+responseInfo);
try {
JSONObject all=new JSONObject(responseInfo);
Log.i(TAG, "onResponse: all="+all);
final String message=all.getString("reason");
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), message,
Toast.LENGTH_LONG).show();
}
});
String result=all.getString("result");
Log.i(TAG, "onSuccess: Phoneresult="+result);
JSONObject jsonObject=new JSONObject(result);
final String province=jsonObject.optString("province");
final String city=jsonObject.optString("city");
final String areacode=jsonObject.optString("areacode");
final String zip=jsonObject.optString("zip");
final String company=jsonObject.optString("company");
final String card=jsonObject.optString("card");
//使用okhttp异步请求方法更改UI时必须切换到主线程
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
text_province.setText(province);
text_city.setText(city);
text_areacode.setText(areacode);
text_zip.setText(zip);
text_company.setText(company);
text_card.setText(card);
text_phone.setText(edit_Search_Phone.getText());
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
布局和其他代码如果有想看的,可以移步
这里,欢迎提出我的不足一起学习。