BoXueGu源码资源下载链接:
BoXueGu图片资源下载(免费):
https://yuyunyaohui.lanzoui.com/iWos0pyc4rc
效果图:
1.导入界面图片
将课程界面所需图片course_intro_icon.png
、chapter_1_ icon.png
、chapter_2_icon.png
、chapter_3_icon.png
、chapter_4_icon.png
、chapter_5_icon.png、chapter_6_icon.png
、chapter_7_icon.png
、chapter_8_icon.png
、chapter_9_icon.png
、chapter_10_icon.png
导入到 drawable
文件夹中。
2.修改布局文件main_view_course.xml
在res/layout
文件夹中的main_view_course.xml
文件添加代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical" >
<include layout="@layout/main_adbanner" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="45dp" >
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:src="@drawable/course_intro_icon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="5dp"
android:gravity="center_vertical"
android:text="@string/course_intro"
android:textColor="@android:color/black"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#E4E4E4" />
<ListView
android:id="@+id/lv_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="55dp"
android:divider="@null"
android:dividerHeight="0dp"
android:scrollbars="none" />
</LinearLayout>
在values文件夹下的string.xml
文件里面输入文本信息:
<string name="course_intro">Android 基础教程1-10章视频</string>
3.课程界面Item
课程界面是使用ListView
控件展示视频列表的, 因此需要创建一个该列表的Item
界面。每个Item中 包含有两个章节信息,每一个章节信息中又包含一个 章节图片、一个章节名称和一个章节概要
在res/layout
文件夹中,创建一个布局文件course_list_item.xml
,具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="140dp"
android:layout_weight="1"
android:orientation="vertical">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="115dp">
<ImageView
android:id="@+id/iv_left_img"
android:layout_width="fill_parent"
android:layout_height="115dp"
android:paddingBottom="4dp"
android:paddingLeft="8dp"
android:paddingRight="4dp"
android:paddingTop="8dp"
android:src="@drawable/chapter_1_icon" />
<TextView
android:id="@+id/tv_left_img_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="4dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="6dp"
android:background="#30000000"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:text="@string/tv_left_img_title"
android:textColor="@android:color/white"
android:textSize="12sp" />
</RelativeLayout>
<TextView
android:id="@+id/tv_left_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:singleLine="true"
android:text="@string/tv_left_title"
android:textColor="@android:color/black"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="140dp"
android:layout_weight="1"
android:orientation="vertical">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="115dp">
<ImageView
android:id="@+id/iv_right_img"
android:layout_width="fill_parent"
android:layout_height="115dp"
android:paddingBottom="4dp"
android:paddingLeft="4dp"
android:paddingRight="8dp"
android:paddingTop="8dp"
android:src="@drawable/chapter_1_icon" />
<TextView
android:id="@+id/tv_right_img_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="10dp"
android:background="#30000000"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:text="@string/tv_right_img_title"
android:textColor="@android:color/white"
android:textSize="12sp" />
</RelativeLayout>
<TextView
android:id="@+id/tv_right_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:singleLine="true"
android:text="@string/tv_right_title"
android:textColor="@android:color/black"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
在values文件夹下的string.xml
文件里面输入文本信息:
<string name="tv_left_img_title">Android 基础入门</string>
<string name="tv_left_title">Android 基础视频第一章</string>
<string name="tv_right_img_title">Android UI开发</string>
<string name="tv_right_title">Android 基础视频第二章</string>
4.修改CourseBean
类
修改china.ynyx.heyunhui.bean
包中的CourseBean.java
文件
package china.ynyx.heyunhui.bean;
public class CourseBean {
public int id; //每章节id
public String icon; //广告栏上的图片
public String imgTitle; //图片上的标题
public String title; //章节标题
public String intro; //章节视频简介
}
5.课程界面Adapter
课程界面的课程列表是用ListView
控件展示的,因此需要创建一个数据适配器 、CourseAdapter
对ListView
控件进行数据适配。由于每个Item分为左右两部分,因此需要 在CourseAdapter
中判断数据是加载到哪个部分的
在 china.ynyx.heyunhui.adapter
包中,创建一个 CourseAdapter
类,继承 BaseAdapter
类
具体代码如下:CourseAdapter.java
package china.ynyx.heyunhui.adapter;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import china.ynyx.heyunhui.R;
import china.ynyx.heyunhui.bean.CourseBean;
public class CourseAdapter extends BaseAdapter {
private Context mContext;
private List<List<CourseBean>> cbl;
public CourseAdapter(Context context) {
this.mContext = context;
}
/**
* 设置数据更新界面
*/
public void setData(List<List<CourseBean>> cbl) {
this.cbl = cbl;
notifyDataSetChanged();
}
/**
* 获取Item的总数
*/
@Override
public int getCount() {
// TODO Auto-generated method stub
return cbl == null ? 0 : cbl.size();
}
/**
* 根据position得到对应Item的对象
*/
@Override
public List<CourseBean> getItem(int position) {
return cbl == null ? null : cbl.get(position);
}
/**
* 根据position得到对应Item的id
*/
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
/**
* 得到相应position对应的Item视图,
* position是当前Item的位置,
* convertView参数就是滚出屏幕的Item的View
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder vh;
if (convertView == null) {
vh = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(
R.layout.course_list_item, null);
vh.iv_left_img = (ImageView) convertView
.findViewById(R.id.iv_left_img);
vh.iv_right_img = (ImageView) convertView
.findViewById(R.id.iv_right_img);
vh.tv_left_img_title = (TextView) convertView
.findViewById(R.id.tv_left_img_title);
vh.tv_left_title = (TextView) convertView
.findViewById(R.id.tv_left_title);
vh.tv_right_img_title = (TextView) convertView
.findViewById(R.id.tv_right_img_title);
vh.tv_right_title = (TextView) convertView
.findViewById(R.id.tv_right_title);
convertView.setTag(vh);
} else {
//复用convertView
vh = (ViewHolder) convertView.getTag();
}
final List<CourseBean> list = getItem(position);
if (list != null) {
for (int i = 0; i < list.size(); i++) {
final CourseBean bean = list.get(i);
switch (i) {
case 0:// 设置左边图片与标题信息
vh.tv_left_img_title.setText(bean.imgTitle);
vh.tv_left_title.setText(bean.title);
setLeftImg(bean.id, vh.iv_left_img);
vh.iv_left_img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到课程详情界面
}
});
break;
case 1:// 设置右边图片与标题信息
vh.tv_right_img_title.setText(bean.imgTitle);
vh.tv_right_title.setText(bean.title);
setRightImg(bean.id, vh.iv_right_img);
vh.iv_right_img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到课程详情界面
}
});
break;
default:
break;
}
}
}
return convertView;
}
/**
* 设置左边图片
*/
private void setLeftImg(int id, ImageView iv_left_img) {
switch (id) {
case 1:
iv_left_img.setImageResource(R.drawable.chapter_1_icon);
break;
case 3:
iv_left_img.setImageResource(R.drawable.chapter_3_icon);
break;
case 5:
iv_left_img.setImageResource(R.drawable.chapter_5_icon);
break;
case 7:
iv_left_img.setImageResource(R.drawable.chapter_7_icon);
break;
case 9:
iv_left_img.setImageResource(R.drawable.chapter_9_icon);
break;
}
}
/**
* 设置右边图片
*/
private void setRightImg(int id, ImageView iv_right_img) {
switch (id) {
case 2:
iv_right_img.setImageResource(R.drawable.chapter_2_icon);
break;
case 4:
iv_right_img.setImageResource(R.drawable.chapter_4_icon);
break;
case 6:
iv_right_img.setImageResource(R.drawable.chapter_6_icon);
break;
case 8:
iv_right_img.setImageResource(R.drawable.chapter_8_icon);
break;
case 10:
iv_right_img.setImageResource(R.drawable.chapter_10_icon);
break;
}
}
class ViewHolder {
public TextView tv_left_img_title, tv_left_title, tv_right_img_title,
tv_right_title;
public ImageView iv_left_img, iv_right_img;
}
}
6.课程界面数据的存放
在assets
文件夹中创建一个chaptertitle.xml
文件,用于存放课程界面的数据。该XML
文件中 包含有章节Id、章节标题、章节图片上的概述,以及章节简介。
具体代码如下:chaptertitle.xml
<?xml version="1.0" encoding="UTF-8"?>
<infos>
<course id="1">
<imgtitle>Android 开发环境搭建</imgtitle>
<title>第1章 Android 基础入门</title>
<intro> Android 是Google公司基于Linux平台开发的手机及平板电脑的操作系统。自问世以来,受到了前所未有的关注,并成为移动平台最受欢迎的操作系统之一。本章将针对Android的基础知识进行详细的讲解。</intro>
</course>
<course id="2">
<imgtitle>Android 五大布局</imgtitle>
<title>第2章 Android UI开发</title>
<intro> Android 程序开发最重要的一个环节就是界面处理,界面的美观度直接影响用户的第一印象,因此,开发一个整齐、美观的界面是至关重要的,本章将针对Android中的UI开发进行详细地讲解。</intro>
</course>
<course id="3">
<imgtitle>Activity 的使用</imgtitle>
<title>第3章 Activity</title>
<intro> 在现实生活中,经常会使用手机进行打电话、发短信、玩游戏等,这就需要与手机界面进行交互。在Android系统中,用户与程序的交互是通过Activity完成的。同时Activity是Android四大组件中最常用的一个,本章将针对Activity的相关知识进行详细的讲解。</intro>
</course>
<course id="4">
<imgtitle>数据存储方式与文件存储</imgtitle>
<title>第4章 数据存储</title>
<intro> 大部分应用程序都会涉及到数据存储,Android程序也不例外。Android中的数据存储方式有五种,分别是文件存储、SharedPreferences、SQLite数据库、ContentProvider以及网络存储。文件存储有很多种形式,XML就是其中的一种,XML存储的数据结构比较清晰,应用比较广泛,因此本章将重点讲解文件存储、XML序列化和解析以及SharedPreferences存储。SQLite数据库、ContentProider和网络存储知识较多并且存储方式与文件存储、SharedPreferences有明显差别,所以放在后边的章节中进行想起讲解。</intro>
</course>
<course id="5">
<imgtitle>SQLite 数据库与ListView</imgtitle>
<title>第5章 SQLite 数据库</title>
<intro> 前面介绍了如何使用SharedPreferences和文件存储来存储数据。但是当需要存储大量数据时,这两种方式显然不合适,为此Android系统中提供了SQLite数据库,它可以存储应用程序中的大量数据,并对数据进行管理和维护。本章将针对SQLite数据库进行详细地讲解。</intro>
</course>
<course id="6">
<imgtitle>广播接收者的类型与使用</imgtitle>
<title>第6章 广播接收者</title>
<intro> 在Android开发中,经常需要访问其他应用程序的数据。例如,使用支付宝转账时需要填写收款人的电话号码,此时就需要获取到系统联系人的信息。为了实现这种跨程序共享数据的功能,Android系统提供了一个组件内容提供者(ContentProvider)。本章将针对内容提供者进行详细地讲解。</intro>
</course>
<course id="7">
<imgtitle>服务创建、启动与生命周期</imgtitle>
<title>第7章 服务</title>
<intro> 在Android系统中,广播(Broadcast)是一种运用在应用程序直接传递消息的机制,广播接收者(BroadcastReceiver)是用来过滤、接收并响应广播的一类组件。通过广播接收者可以监听系统中的广播消息,在不同组件之间进行通信。本章将为大家讲解广播接收者的相关知识。</intro>
</course>
<course id="8">
<imgtitle>内容提供者的使用</imgtitle>
<title>第8章 内容提供者</title>
<intro> 服务与Activity类似,不同的是服务没有界面,是一个长期运行在后台的组件,即使启动服务的应用程序被切换掉,其他的Service也可以在后台正常运行,因此Service经常被用来处理一些耗时的程序,例如进行网络传输或者播放音乐等。本章将针对服务进行详细地讲解。</intro>
</course>
<course id="9">
<imgtitle>访问网络与数据提交方式</imgtitle>
<title>第9章 网络编程</title>
<intro> Android 由互联网巨头Google带头开发,因此Android对网络功能的支持是必不可少的,Android系统提供了一下几种方式实现网络通信,本章将会讲解如何在手机端使用HTTP协议和与服务器端进行网络交互。</intro>
</course>
<course id="10">
<imgtitle>动画、多媒体、传感器等</imgtitle>
<title>第10章 高级编程</title>
<intro> 前面 九章都是针对Android基础知识进行讲解,掌握好这些知识可以开发天气预报、新闻客户端等程序。为了让初学者能够更全面地掌握Android知识,本章将针对图形图像处理、多媒体、传感器、Fragment等高级编程知识进行详细地讲解。</intro>
</course>
</infos>
7.修改工具类
由于课程界面的视频列表数据存放在assets
文件夹下的chaptertitle.xml
文件中,因此 需要在AnalysisUtils.java
文件中添加一 个解析XML
的方法getCourselnfos()
,具体代码如下:
/**
* 解析每章的课程视频信息
*/
public static List<List<CourseBean>> getCourseInfos(InputStream is) throws Exception {
XmlPullParser parser=Xml.newPullParser();
parser.setInput(is, "utf-8");
List<List<CourseBean>> courseInfos=null;
List<CourseBean> courseList=null;
CourseBean courseInfo=null;
int count=0;
int type=parser.getEventType();
while (type!=XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if("infos".equals(parser.getName())){
courseInfos=new ArrayList<List<CourseBean>>();
courseList=new ArrayList<CourseBean>();
}else if("course".equals(parser.getName())){
courseInfo=new CourseBean();
String ids=parser.getAttributeValue(0);
courseInfo.id=Integer.parseInt(ids);
}else if("imgtitle".equals(parser.getName())){
String imgtitle=parser.nextText();
courseInfo.imgTitle=imgtitle;
}else if("title".equals(parser.getName())){
String title=parser.nextText();
courseInfo.title=title;
}else if("intro".equals(parser.getName())){
String intro=parser.nextText();
courseInfo.intro=intro;
}
break;
case XmlPullParser.END_TAG:
if("course".equals(parser.getName())){
count++;
courseList.add(courseInfo);
if(count%2==0){// 课程界面每两个数据是一组放在List集合中
courseInfos.add(courseList);
courseList=null;
courseList=new ArrayList<CourseBean>();
}
courseInfo=null;
}
break;
}
type=parser.next();
}
return courseInfos;
}
8.课程界面逻辑代码
修改china.ynyx.heyunhui.view
包中的CourseView.java
文件
(1)public class CourseView {
下添加:
private ListView lv_list;
private CourseAdapter adapter;
private List<List<CourseBean>> cbl;
(2)mCurrentView = mInflater.inflate(R.layout.main_view_course, null);
下添加:
lv_list = (ListView) mCurrentView.findViewById(R.id.lv_list);
adapter = new CourseAdapter(mContext);
adapter.setData(cbl);
lv_list.setAdapter(adapter);
(3) 在最后添加:
/**
* 获取课程信息
*/
private void getCourseData() {
try {
InputStream is = mContext.getResources().getAssets().open("chaptertitle.xml");
cbl = AnalysisUtils.getCourseInfos(is);//getCourseInfos(is)方法在下面会有说明
} catch (Exception e) {
e.printStackTrace();
}
}
(4) 调用getCourseData()
,在private void createView() {
下添加:
getCourseData();
一定要放到new AdAutoSlidThread().start();
上方,如:
private void createView() {
mHandler = new MHandler();
initAdData();
getCourseData();
initView();
new AdAutoSlidThread().start();
}
参考资料:《android项目实战——博学谷》(黑马程序员著)