上一节对欢迎模块进行了综述(可参见 2. 欢迎模块 进行了解),接下来将从首页模块开始详细介绍:
知识点:
- 掌握 Python学科模块的开发,实现界面的显示
- 掌握首页界面与Python学科界面的数据获取与数据解析逻辑流程
Python学科:
任务综述:
在项目中,点击首页中的四个学科(Python、Java、PHP、Android)按钮,分别会跳转到对应学科的界面,该界面展示的是对应学科在全国各个分校的开班地址和开班情况等信息,各个学科界面的数据以JSON格式存放在Tomcat服务器,在各个界面的逻辑代码中,调用gson库解析获取的JSON数据并展示在对应学科的界面上。
1. “Python学科”界面
任务分析:
首页中的四个学科(Python、Java、PHP、Android)按钮,分别会跳转到对应学科的界面,该界面展示的是对应学科在全国各个分校的开班地址和开班情况等信息,此处以Python学科为例,界面如图所示。
任务实施:
(1)创建“Python学科”界面。在com.XXXX.newsdemo.activity包中创建PythonActivity,该界面与首页界面新闻列表的布局类似,因此该界面调用首页界面的布局文件fragment_home.xml。
(2)导入界面图片。(fire_icon)
(3)修改fragment_home.xml。由于Python学科设有标题栏,而fragment_home.xml文件中只有下拉刷新与WrapRecyclerView列表,因此需要在该文件的com.itheima.PullToRefreshView控件上方引入标题栏。
<include layout="@layout/main_title_bar" />
(4)修改HomeFragment类。由于fragment_home.xml文件引入了标题栏,但是首页吧界面的新闻列表不能显示标题栏,因此需要在首页界面的逻辑代码中把标题栏设置为不可见的状态,找到该文件的“private HomeListAdapter adapter;”语句下方添加如下代码:
private RelativeLayout rl_title_bar;
在该文件的initView()方法中的“View view = inflater.inflate(R.layout.fragment_home,container,false);”语句下方添加如下代码:
rl_title_bar = (RelativeLayout) view.findViewById(R.id.title_bar);
rl_title_bar.setVisibility(View.GONE);
2. “Python学科”界面Item
任务分析:
“Python学科”界面通过使用WrapRecyclerView控件展示开班信息列表,因此需要创建一个该列表的Item界面。在Item界面中需要展示开班地址,开班内容以及“火”的图标,界面效果如图所示。
任务实施:
(1)创建“Python学科”界面Item。在res/layout文件夹中创建布局文件python_list_item.xml。
(2)放置界面控件。在布局文件中,放置两个TextView控件分别用于显示分校地址与开班情况;一个ImageView控件用于显示“火”的图标,一个View控件用于显示一条灰色的线。
python_list_item.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="40dp"
android:background="@android:color/white"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<TextView
android:id="@+id/tv_address"
android:layout_width="60dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:background="@color/rdTextColorPress"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@id/tv_address"
android:textColor="@android:color/black"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_fire"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:scaleType="fitXY"
android:src="@drawable/fire_icon" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/tv_address"
android:background="@android:color/darker_gray" />
</RelativeLayout>
3. 创建PythonBean
任务分析:
由于“Python学科”界面的每个Item中都有开班Id、开办地址、开办内容等属性,因此可以创建一个PythonBean类存放这些属性。
任务实施:
在com.XXXX.newsdemo.bean包中创建一个PythonBean类,在该类中创建Python学科开班信息的所有属性。
PythonBean.java
public class PythonBean {
private int id; //开班Id
private String address; //开班地址
private String content; //开班内容
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
4. “Python学科”界面Adapter
任务分析:
“Python学科”界面的开班信息列表是通过WrapRecyclerView控件展示的,因此需要创建一个数据适配器PythonListAdapter对WrapRecyclerView控件进行数据适配。
任务实施:
(1)创建PythonListAdapter类。在com.XXXX.newsdemo.adapter包中创建一个PythonListAdapter类继承RecyclerView.Adapter<RecyclerView.ViewHolder>类,并重写onCreateViewHolder()、onBindViewHolder()、getItemCount()方法。
(2)创建PythonViewHolder()类。在PythonListAdapter类中创建一个PythonViewHolder类以获取Item界面上的控件。
PythonListAdapter.java
public class PythonListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<PythonBean> pbl;
public void setData(List<PythonBean> pbl) {
this.pbl = pbl;
notifyDataSetChanged();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
{
View view = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.python_list_item, viewGroup, false);
PythonViewHolder viewHolder = new PythonViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int i) {
final PythonBean bean = pbl.get(i);
((PythonViewHolder) holder).tv_address.setText(bean.getAddress());
((PythonViewHolder) holder).tv_content.setText(bean.getContent());
}
@Override
public int getItemCount() {
return pbl == null ? 0 : pbl.size();
}
public class PythonViewHolder extends RecyclerView.ViewHolder {
private TextView tv_address, tv_content;
public ImageView iv_img;
public PythonViewHolder(View itemView) {
super(itemView);
tv_address = (TextView) itemView.findViewById(R.id.tv_address);
tv_content = (TextView) itemView.findViewById(R.id.tv_content);
iv_img = (ImageView) itemView.findViewById(R.id.iv_fire);
}
}
}
5. “Python学科”界面逻辑代码
任务分析:
“Python学科”界面上加载的数据需要在Tomcat服务器上设置,同时需要在JsonParse类中创建getPythonList()方法用于解析从服务器上获取的JSON格式的数据。
任务实施:
(1)创建“Python学科”界面数据文件。在Tomcat的ROOT/newsdemo目录中创建一个python_list_data.json文件,该文件用于存放Python界面需要加载的数据。
python_list_data.json
[
{
"id":1,
"address":"北京",
"content":"人工智能+Python基础班2017-08-18",
"open_class":"我要报名"
},
{
"id":2,
"address":"北京",
"content":"人工智能+Python基础班2017-07-27",
"open_class":"我要报名"
},
……由于数据量太大,此处省略一部分数据
{
"id":23,
"address":"在线学习",
"content":"人工智能+Python在线班2017-06-29",
"open_class":"我要报名"
}
]
(2)在Constant.java文件中添加请求地址。由于“Python学科”界面的数据是从服务器获取的,因此需要找到utils包下的Constant.java,在该文件中添加“Python学科”界面请求数据需要的地址:
public static final String REQUEST_PYTHON_URL = "/python_list_data.json";
(3)解析JSON数据。由于从Tomcat服务器上获取的JSON格式的数据不能直接加载到界面上,因此需要在utils包的JaonParse类中创建一个getPythonList()方法,用于解析该界面的JSON数据,在JsonParse类中需要添加以下代码:
public List<PythonBean> getPythonList(String json) {
//使用gson库解析JSON数据
Gson gson = new Gson();
//创建一个TypeToken的匿名子类对象,并调用对象的getType()方法
Type listType = new TypeToken<List<PythonBean>>() {}.getType();
//把获取到的信息集合存到pythonList中
List<PythonBean> pythonList = gson.fromJson(json, listType);
return pythonList;
}
(4)获取数据。在PythonActivity中创建一个initData()方法,用于获取“Python学科”界面需要加载的数据。
(5)获取界面控件。在PythonActivity中创建界面控件的初始化方法initView(),用于获取“Python学科”界面所要用到的控件。
PythonActivity.java
public class PythonActivity extends AppCompatActivity {
private SwipeBackLayout layout;
private PullToRefreshView mPullToRefreshView;
private WrapRecyclerView recycleView;
public static final int REFRESH_DELAY = 1000;
public static final int MSG_PYTHON_OK = 1; //获取数据
private TextView tv_main_title, tv_back;
private RelativeLayout rl_title_bar;
private MHandler mHandler;
private PythonListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = (SwipeBackLayout) LayoutInflater.from(this).inflate(
R.layout.base, null);
layout.attachToActivity(this);
setContentView(R.layout.fragment_home);
mHandler = new MHandler();
initData();
initView();
}
private void initView() {
tv_main_title = (TextView) findViewById(R.id.tv_main_title);
tv_main_title.setText("Python学科");
rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
rl_title_bar.setBackgroundColor(getResources().getColor(
R.color.rdTextColorPress));
tv_back = (TextView) findViewById(R.id.tv_back);
tv_back.setVisibility(View.VISIBLE);
recycleView = (WrapRecyclerView) findViewById(R.id.recycler_view);
recycleView.setLayoutManager(new LinearLayoutManager(this));
adapter = new PythonListAdapter();
recycleView.setAdapter(adapter);
mPullToRefreshView = (PullToRefreshView) findViewById(R.id.pull_to_refresh);
mPullToRefreshView.setOnRefreshListener(new PullToRefreshView.
OnRefreshListener(){
@Override
public void onRefresh() {
mPullToRefreshView.postDelayed(new Runnable() {
@Override
public void run() {
mPullToRefreshView.setRefreshing(false);
initData();
}
}, REFRESH_DELAY);
}
});
tv_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PythonActivity.this.finish();
}
});
}
private void initData() {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(Constant.WEB_SITE +
Constant.REQUEST_PYTHON_URL).build();
Call call = okHttpClient.newCall(request);
//开启异步线程访问网络
call.enqueue(new Callback() {
@Override
public void onResponse(Response response) throws IOException {
String res = response.body().string();
Message msg = new Message();
msg.what = MSG_PYTHON_OK;
msg.obj = res;
mHandler.sendMessage(msg);
}
@Override
public void onFailure(Request arg0, IOException arg1) {
}
});
}
/**
* 事件捕获
*/
class MHandler extends Handler {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case MSG_PYTHON_OK:
if (msg.obj != null) {
String vlResult = (String) msg.obj;
//使用Gson解析数据
List<PythonBean> pythonList = JsonParse.getInstance().
getPythonList(vlResult);
adapter.setData(pythonList);
}
break;
}
}
}
}
(6)修改HomeFragment.java文件。由于点击首页界面的“Python学科”按钮会跳转到“Python学科”界面,因此需要找到首页模块(三)之首页HomeFragment.java中的setListener()方法,在该方法的onClick()方法中添加如下代码:
Intent intent = new Intent(getActivity(), PythonActivity.class);
startActivity(intent);
(7)修改清单文件。由于“Python学科”界面向右滑动会关闭该界面,因此需要给该界面添加透明主题样式,在清单文件中的PythonActivity对应的activity标签中添加如下代码:
android:theme="@style/AppTheme.TransparentActivity"