本項目是用eclipse軟件編寫,經過我的親自實踐,其真實有效,希望能給您有所幫助😘😘
項目版本:android5.1.1 AVD建議:android4.4.2及以上 若有不足之處或不對的地方,歡迎大佬們指點 |
文章目錄
效果圖:
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項目實戰——博學谷》(黑馬程序員著)