仿牛客UI Android版

来源:互联网 发布:ubuntu删除文件夹 编辑:程序博客网 时间:2024/06/01 09:59

这是我的第一篇博客,想想还有点小。鸡。动。。。
这篇博客是写给初学者的,也是给自己留个记录以备日后查看。大神们就路过吧!不喜勿喷,有不正的地方还望不吝赐教!事先声明只实现该app的部分功能和UI。


特别声明一下

【标题栏(ActionBar)部分牛客的标题可以向上滑动隐藏,可以使用安卓的suppost-V7实现,为节省时间直接在布局中写出来了,下拉刷新功能也没有实现,app所涉及到的数据均存放在安卓sqlite数据库内。】

代码目录预览:
预览图1
预览图2

布局目录预览:
预览图3


以下是正文:

主界面布局: 底部使用四个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


3 0
原创粉丝点击