这是我的第一篇博客,想想还有点小。鸡。动。。。
这篇博客是写给初学者的,也是给自己留个记录以备日后查看。大神们就路过吧!不喜勿喷,有不正的地方还望不吝赐教!事先声明只实现该app的部分功能和UI。
特别声明一下
【标题栏(ActionBar)部分牛客的标题可以向上滑动隐藏,可以使用安卓的suppost-V7实现,为节省时间直接在布局中写出来了,下拉刷新功能也没有实现,app所涉及到的数据均存放在安卓sqlite数据库内。】
代码目录预览:
布局目录预览:
以下是正文:
主界面布局: 底部使用四个RelativeLayout(学习、社区、消息、我的牛客) + 中间自定义ViewPager(禁止滑动)
主代码写在MainActivity里面,思路:底部四个相对布局(RelativeLayout)相当于四个按钮,点击可跳到ViewPager不同的位置,而ViewPager的每个位置存放了不同的Fragment,因为本身个别Fragment内含有可滑动的ViewPager所以必须取消当前ViewPager的滑动监听以免其内部ViewPager不能响应!
1.自定义ViewPager - CustomViewPager重写onTouchEvent(MotionEvent arg0)和onInterceptTouchEvent(MotionEvent arg0)两个事件
private boolean canScroll;
public CustomViewPager(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if (canScroll) {
return super.onInterceptTouchEvent(arg0);
} else {
return false;
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent arg0) {
if (canScroll) {
return super.onTouchEvent(arg0);
}else {
return false;
}
}
/**
* @param canScroll the canScroll to set
*/
public void setCanScroll(boolean canScroll) {
this.canScroll = canScroll;
}
个人理解
return true:表示当前事件被消费完毕,不会继续向下分发
return false:表示当前事件未被消费完毕,会继续向下分发
2.将4个Fragment放入自定义ViewPager(CustomViewPager)中可以使用FragmentPagerAdapter也可以使用PagerAdapter,这里使用前者。
定义CustomFragementAdapter类继承自FragmentPagerAdapter。
需要传入FragmentManager 和四个Fragment。重写/实现三个方法。
private List<Fragment> fragments;
public CustomFragementAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return fragments.size();
}
@Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
return fragments.get(arg0);
}
如果使用的是安卓v4的兼容包MainActivity需要继承自FragmentActivity,FragmentManager需要用getSupportFragmentManager。
接下来就是4个Fragment里面的东西了。
学习:StudyFragment
社区:CommunityFragment(ViewPager + PagerSlidingTabStrip)
消息:MessageFragment (ViewPager + PagerSlidingTabStrip)
我的牛客:ProfileFragment 只有布局不讲解。
上面用到的PagerSlidingTabStrip是第三方的一个组件,貌似安卓某兼容库也有类似功能的(懒得整)。每个Fragment需要继承自Fragment(我用的V4包里的android.support.v4.app.Fragment)。
社区(CommunityFragment)和 消息(MessageFragment )放一起说吧。这两个很相似。都可以用在View中嵌套ListView然后放到ViewPager中的方式实现。
1.以CommunityFragment为例。重写/实现onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)。填充一个View作为返回。
View view = inflater.inflate(R.layout.fragment_community,container,false);
所有视图上的组件用view.findViewById()进行绑定。社区界面有9个滑动界面(刚刚使用了FragmentPagerAdapter)这里使用PagerAdapter进行填充。只要将数据以View的形式传进去就行了。
private ViewPager pager;
private PagerSlidingTabStrip mTab;
private ViewAdapter adapter;
private ListView[] lv;
private int mTextColorNormal = Color.BLACK;
private int mTextColorSelected = Color.parseColor("#ff00bb99");
private CommunityAdapter cAdapter;
@SuppressLint("InflateParams")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_community, container,false);
pager = (ViewPager)view.findViewById(R.id.communitypager);
mTab = (PagerSlidingTabStrip) view.findViewById(R.id.communitytabs);
mTab.setSelectedTextColor(mTextColorSelected);
mTab.setTextColor(mTextColorNormal);
mTab.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()));
mTab.setIndicatorColor(mTextColorSelected);
mTab.setBackgroundColor(Color.WHITE);
mTab.setDividerColor(Color.TRANSPARENT);
ArrayList<String> titles = new ArrayList<String>();
titles.add("全部");
titles.add("技术交流");
titles.add("笔试面经");
titles.add("随便聊聊");
titles.add("站内公告");
titles.add("资源分享");
titles.add("我要提问");
titles.add("招聘信息");
titles.add("工作感受");
lv = new ListView[titles.size()];
List<View> views = new ArrayList<View>();
List<CommunityItem> data = new ArrayList<CommunityItem>();
DBManager dbManager = new DBManager(getActivity());
View mView;
for (int i = 0; i < 9; i++) {
mView = LayoutInflater.from(getActivity()).inflate(
R.layout.communitylist, null, false);
data = dbManager.getCommunityItem(i);
Log.i(TAG, "" + data.size());
lv[i] = (ListView) mView.findViewById(R.id.commlist);
cAdapter = new CommunityAdapter(getActivity(), data);
lv[i].setAdapter(cAdapter);
Log.i("TAG", "" + cAdapter.getCount());
views.add(mView);
}
adapter = new ViewAdapter(views, titles);
pager.setAdapter(adapter);
mTab.setViewPager(pager);
return view;
}
有几个滑动页面就需要填充几个View 每一个view需要一个ListView。这里的ListVIew也需要适配器稍后讲。
2.给ViewPager自定义适配器(ViewAdapter)这里我使用的是PagerAdapter。然后把View和标题传进去。
private List<View> views;//View列表
private List<String> titles;//标题列表
public ViewAdapter(List<View> views, List<String> titles) {
this.views = views;
this.titles = titles;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position));
//super.destroyItem(container, position, object);
}
@Override
public int getCount() {
return views.size();
}
@Override
public CharSequence getPageTitle(int position) {
if (titles != null) {
return titles.get(position);
}
return super.getPageTitle(position);
}
@Override
public View instantiateItem(ViewGroup container, int position) {
container.addView(views.get(position));
return views.get(position);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
3.上面的每个刚刚说道ListView也需要适配器,自定义适配器(CommunityAdapter)继承自BaseAdapter传入数据和上下文对象。
private List<CommunityItem> data;
private Context context;
public CommunityAdapter(Context context, List<CommunityItem> data) {
this.data = data;
this.context = context;
}
@Override
public int getCount() {
return data.size();
}
@Override
public CommunityItem getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
class ViewHolder {
public ImageView head;
public TextView name;
public TextView relayTime;
public TextView title;
public TextView summary;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View view = null;
if (view == null) {
view = LayoutInflater.from(context).inflate(
R.layout.community_list_item, null, false);
}
holder.head = (ImageView) view.findViewById(R.id.head);
holder.name = (TextView) view.findViewById(R.id.name);
holder.relayTime = (TextView) view.findViewById(R.id.lastRelayTime);
holder.title = (TextView) view.findViewById(R.id.title);
holder.summary = (TextView) view.findViewById(R.id.summary);
CommunityItem item = data.get(position);
holder.head.setImageResource(item.getHead());
holder.name.setText(item.getName());
String category = "未分类";
switch (item.getType()) {
case 1:
category = "技术交流";
break;
case 2:
category = "笔试面经";
break;
case 3:
category = "随便聊聊";
break;
case 4:
category = "站内公告";
break;
case 5:
category = "资源分享";
break;
case 6:
category = "我要提问";
break;
case 7:
category = "招聘信息";
break;
case 8:
category = "工作感受";
break;
default:
break;
}
holder.relayTime.setText(item.getLastRelayTime() + "【" + category
+ "】");
holder.title.setText(item.getTitle());
holder.summary.setText(item.getSummary());
return view;
}
最后一个部分:StduyFragment只说明“专项学习”(IntelliTestActivity)点进去的界面,这个我使用拓展列表(ExpandableListView)做的适配器使用的是(ExpandableAdapter)继承自BaseExpandableListAdapter
private static final String TAG = "ExpandableAdapter";
private Context context;
private List<ExpandableItem> data;
public ExpandableAdapter(Context context, List<ExpandableItem> data) {
this.context = context;
this.data = data;
}
@Override
public int getGroupCount() {
return data.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return data.get(groupPosition).getItemList().size();
}
@Override
public ExpandableItem getGroup(int groupPosition) {
return data.get(groupPosition);
}
@Override
public ExpandableSubItem getChild(int groupPosition, int childPosition) {
return data.get(groupPosition).getItemList().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return data.get(groupPosition).getGroupId();
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return data.get(groupPosition).getItemList().get(childPosition)
.getSubjectId();
}
@Override
public boolean hasStableIds() {
return false;
}
private TextView catgroy;
private TextView indicator;
@SuppressLint("InflateParams")
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.expandable_list_item, null);
catgroy = (TextView)convertView.findViewById(R.id.catgroy);
indicator = (TextView)convertView.findViewById(R.id.indicator);
ExpandableItem expand = data.get(groupPosition);
catgroy.setText(expand.getCatgroy());
if (isExpanded) {
indicator.setBackgroundResource(R.drawable.arror_up);
Log.i(TAG, "" + isExpanded);
} else {
indicator.setBackgroundResource(R.drawable.arror_down);
}
return convertView;
}
private TextView subjectName;
private TextView subjectTotal;
private TextView subjectDone;
private Button exercise;
@SuppressLint("InflateParams")
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.expandable_sub_list_item, null);
subjectName = (TextView) convertView
.findViewById(R.id.subject_name);
subjectTotal = (TextView) convertView
.findViewById(R.id.subject_total);
subjectDone = (TextView) convertView
.findViewById(R.id.subject_done);
exercise = (Button) convertView.findViewById(R.id.exercise);
}
final ExpandableSubItem item = data.get(groupPosition).getItemList()
.get(childPosition);
subjectName.setText(item.getSubjectName());
subjectTotal.setText("共" + item.getSubjectTotal() + "道题");
subjectDone.setText("已练习" + item.getSubjectTotal() + "题");
exercise.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, TestMainActivity.class);
intent.putExtra("what", item.getSubjectId());//what指的是subject的id,用id去查找相应的题目
context.startActivity(intent);
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
最后的抽题模块:我把它写成了一个类RandomQuestions。可以随机抽出题目,以及题目的选项。
private static final String TAG = "RandomQuestions";
private Context context;
public RandomQuestions(Context context) {
this.context = context;
}
/**
*
* @param what
* 课程类型
* @param number
* 需要的题数
* @return
*/
public List<QuestionItem> getRadomQuestions(int what, int number) {
if (number < 1) {
return null;
}
int[] counts = getCounts(number, 11); // 数据库共11题,相当于题目id
List<QuestionItem> questions = new ArrayList<QuestionItem>();
DBManager dbManager = new DBManager(context);
for (int i = 0; i < counts.length; i++) {
questions.add(dbManager.getQuestion(what, counts[i]));
}
return questions;
}
/*
* public static void main(String[] args) {
*
* getCounts(10); }
*/
/**
* 随机生成不相同的数组
*
* @param number
* 所需题目数
* @param total
* 题目总数
* @return
*/
public static int[] getCounts(int number, int total) {
int[] counts = new int[number];
Random random = new Random();
int index = 0;
boolean replace = true;
int c;
while (index < number) {
c = random.nextInt(total) + 1;
for (int i = 0; i < index + 1; i++) {
if (c == counts[i]) {
replace = false;
break;
}
}
if (replace) {
counts[index] = c;
Log.i(TAG, "counts:" + counts[index]);
index++;
}
replace = true;
}
return counts;
}
项目源码下载地址:
http://download.csdn.net/detail/u013271384/9418443