安卓 仿学习app项目

来源:互联网 发布:中欧基金 知乎 编辑:程序博客网 时间:2024/05/18 01:26

之前写过一个项目,想把自己写的里面的一些技术点记录下来,也相当于给自己做笔记。同时也跟大家一起分享一下,若碰到同样的问题的朋友,也可以相互交流一下,新手上路,请多多指教。在那期间呢,碰到以及出现过许多的错误,这里就在这记录一下。

1、关于找错:这仅对于新手来说:1、当你思路不清楚时,或你为什么达不到你要的效果时,你要学会从头理,理清顺序,看自己是在哪个环节哪个步骤写错了,比如可能你的方法没写全之类的小问题,这要耐心,毕竟心急吃不了热豆腐。

2、高级控件自动补全 《Autocompl》 同一个适配器(adapter)可以作用于多个数据 需要通过适配器拿到数据 一般默认两个(也就是要写两个字符串才提示) 如需默认一个需加属性complettionThreshold=”1” (2,)多个自动补全框《multiautocopleteTextview》 分割符: 默认逗号 new multAutocompl 下拉列表 《spinner》 listview 集合

3、如果一个项目区间引用第三方控件 如果要删除第三方控件的话 其另一个引用他的控件也要删除其引用的那行代码

4、解析viewpager+xml 只需解析布局 主要代码如下:

 View chanese= LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_chinese,null);

但解析viewpager+activity需要得到布局 也需要其activity (包含java代码)主要代码如下:

LocalActivityManager manager=new   LocalActivityManager(this,true);   manager.dispatchCreate(savedInstanceState);
Intent intent=new Intent(MainActivity.this,ChineseActivity.class);    View   chinese= manager.startActivity("viewID",intent).getDecorView();//转成view

5、数据库版本问题 不能一个大 一个小 只能一起升级 这样就不会报版本号的错误

接下来就讲讲我项目中用到的一些技术点吧,由于一些问题我就不截图了:

首先当app首次安装必定有个导航页;

其用到的是 sharedprefence+viewpager+handler

刚开始进是有个欢迎界面,在欢迎界面里面判断你是否是第一次进入;其代码如下:

activity:

import android.content.Intent;import android.content.SharedPreferences;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.Toast;public class WelcomeActivity extends AppCompatActivity {    @Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_welcome);        shipToNavigationOrFrame();    }    //判断且实现应跳转导航动画还是主界面private void shipToNavigationOrFrame() {      //  Toast.makeText(WelcomeActivity.this, "3333", Toast.LENGTH_SHORT).show();boolean firstFlag; //是否首次安装SharedPreferences sharedPreferences = getSharedPreferences("flag", MODE_PRIVATE);        firstFlag = sharedPreferences.getBoolean("first", true);        final Intent intent = new Intent();        if (firstFlag) {         //   Toast.makeText(WelcomeActivity.this, "4444", Toast.LENGTH_SHORT).show();intent.setClass(this, NavigationActivity.class);            SharedPreferences.Editor editor = sharedPreferences.edit();            editor.putBoolean("first", false);            editor.apply(); //apply与commit作用相同,虽没返回值,但效率更高} else {            intent.setClass(this, SplashhActivity.class);        }        new Handler().postDelayed(new Runnable() { //延时1.5秒@Overridepublic void run() {                startActivity(intent);                WelcomeActivity.this.finish();                finish();            }        },1500);}}

其对应的xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_welcome"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"tools:context="com.example.activity_appui.WelcomeActivity"android:background="@drawable/welcome"></LinearLayout>

接下来就是导航页了,其代码如下:

activity:

import android.content.Intent;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class NavigationActivity extends AppCompatActivity {    private ViewPager vPager;    private ViewGroup pointGroup;    private List vList;    private ImageView[] pointImgViews; //装载导航小圆点@Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_navigation);       /// Toast.makeText(NavigationActivity.this, "555", Toast.LENGTH_SHORT).show();initView();        setvPager();        addPoints();        setAdapterForViewPager();    }    //加载主页面控件private void initView(){       // Toast.makeText(NavigationActivity.this, "555", Toast.LENGTH_SHORT).show();vPager = (ViewPager)findViewById(R.id.navigation_vp);        pointGroup = (ViewGroup)findViewById(R.id.viewPoints);      //  getSupportActionBar().hide();}    private void setvPager(){        LayoutInflater inflater = getLayoutInflater();        vList = new ArrayList<View>();        vList.add(inflater.inflate(R.layout.navigation_page,null));        vList.add(inflater.inflate(R.layout.navigation_page2,null));        vList.add(inflater.inflate(R.layout.navigation_page3,null));        PagerAdapter myAdapter = new PagerAdapter(){            @Overridepublic int getCount() {                return vList.size();            }            @Overridepublic void destroyItem(ViewGroup container, int position, Object object) {                // super.destroyItem(container, position, object);container.removeView((View) vList.get(position));            }            @Overridepublic Object instantiateItem(ViewGroup container, int position) {                container.addView((View) vList.get(position));                return vList.get(position);            }            @Overridepublic boolean isViewFromObject(View view, Object object) {                return view==object;            }        };        vPager.setAdapter(myAdapter);    }    private  void addPoints(){        ImageView pointImgView;        pointImgViews = new ImageView[vList.size()]; //确定小圆点的个数        //动态添加小圆点for(int i=0; i<vList.size(); i++) {            pointImgView = new ImageView(NavigationActivity.this);            pointImgView.setLayoutParams(new ViewGroup.LayoutParams(25, 25)); //设置圆点大小pointImgView.setPadding(5, 0, 5, 0);            pointImgViews[i] = pointImgView;            // 默认选中的是第一张图片,此时第一个小圆点是选中状态,其他不是if (i == 0)                pointImgViews[i].setImageDrawable(getResources().getDrawable(                        R.drawable.i1));            elsepointImgViews[i].setImageDrawable(getResources().getDrawable(                        R.drawable.i3));            // 将imageviews添加到小圆点视图组pointGroup.addView(pointImgViews[i]);        }    }    //添加监听器,将相应页面的小圆点设置为选中状态private void setAdapterForViewPager(){        vPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()        {            @Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {            }            @Overridepublic void onPageSelected(int position) {                for (int i = 0; i < pointImgViews.length; i++) {                    // 当前view下设置小圆点为未选中状态pointImgViews[i].setImageDrawable(getResources().getDrawable(                            R.drawable.i1));                    //设置小圆点为选中状态if(position == i)                        pointImgViews[i].setImageDrawable(getResources().getDrawable(                                R.drawable.i3));                }            }            @Overridepublic void onPageScrollStateChanged(int state) {            }        });    }    //点击button后调用,跳转到主界面,勿忘设置参数public void shipToFrame(View v){        Intent intent = new Intent(this, DownActivity.class);        startActivity(intent);        this.finish();    }}

xml:

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"tools:context="com.example.activity_appui.NavigationActivity">    <android.support.v4.view.ViewPagerandroid:id="@+id/navigation_vp"android:layout_width="match_parent"android:layout_height="match_parent"/>    <LinearLayoutandroid:id="@+id/viewPoints"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_gravity="bottom"android:layout_marginBottom="15dp"android:gravity="center_horizontal"android:orientation="horizontal"android:paddingBottom="150dp">    </LinearLayout></FrameLayout>

因为导航页就是一张张滑动的,就用viewpager+activity,activity里面就放张图片,这里就贴一个activity出来,其余都是一样的。

xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_height="match_parent"android:layout_width="match_parent"android:background="@drawable/navigation_image"></RelativeLayout>

这样就能实现导航页了。当你第二次登录时,你便进入引导页,像qq那样每次进去便出现那个熟悉的小企鹅。可以用countdonwntime,线程也可以实现这个效果。本人就是用线程实现的。代码如下:

activity:

import android.content.Intent;import android.content.SharedPreferences;import android.os.Handler;import android.os.Message;import android.os.SystemClock;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class SplashhActivity extends AppCompatActivity {    private ImageView splash_img;    private TextView tv_control;    private TextView tv_control2;    private Intent intent;    private Thread thread;    private boolean bool;    @Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_splashh);        splash_img = (ImageView) findViewById(R.id.splash_img);        tv_control = (TextView) findViewById(R.id.tv_control);        tv_control2 = (TextView) findViewById(R.id.tv_control2);       // 跳转页面intent = new Intent(SplashhActivity.this, DownActivity.class);        bool = true;        thread = new Mythread();        thread.start();    }    //处理Handler handler = new Handler() {        public void handleMessage(Message msg) {            super.handleMessage(msg);            int i = msg.what;            tv_control.setText(i + "秒");        }    };    public void jump(View view) {        bool = false;        //开始跳startActivity(intent);        finish();    }    //子线程class Mythread extends Thread {        @Overridepublic void run() {            super.run();            for (int i = 5; i >= 0; i--) {                handler.sendEmptyMessage(i);                SystemClock.sleep(1000);            }            //当他等于true的时候跳while (bool) {                //跳转 Intent 意图Intent intent = new Intent(SplashhActivity.this, DownActivity.class);                //开始跳startActivity(intent);                break;            }            //直接返回主页面finish();        }    }}

xml:

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_splashh"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.activity_appui.SplashhActivity">    <ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/g_1"android:id="@+id/splash_img"android:scaleType="fitXY"/>    <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/tv_control"android:background="#3f5348"android:textSize="30sp"android:layout_gravity="right"android:text="倒计时"/>    <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/tv_control2"android:background="#3f5348"android:textSize="30sp"android:layout_gravity="bottom|right"android:onClick="jump"/></FrameLayout>

进了引导页之后自然便进入主界面,主界面排版:textview,ViewPager,ViewPager+fragment…….
其中用ViewPager实现图片自动播放加点击事件,一般像一个学习app这样的功能就是点击任意一张图片你便能进入其自己app公众号或是其自己的网站还有的就是广告。
其代码如下:

activity:private ImageView topmain_imags;//得到图片集合int images[] = {R.drawable.guid1, R.drawable.guid2, R.drawable.guid3, R.drawable.guid4};//定义一个全局变量 当前的变量为0int currentIndex = 0;private Thread thread;private Spinner main_spinner;private TextView tv_class;private TextView tv_c1;private ListView lv_main;private ViewPager vp_viewpage_activity;private List<View> list;//表示装载滑动的布局private RadioGroup rp_grooup_clazz;private RadioGroup rg_main;List<Fragment> view = new ArrayList<>();private RadioGroup rg_down;private Button rb_study;private Button rb_find;private Button rb_my;private ViewPager vp;private List<View> views = new ArrayList<View>();private ImageView iv, iv2;//iv代表小圆点,iv2代表viewPager的图片private int images2[] = {R.drawable.guid1, R.drawable.guid2, R.drawable.guid3, R.drawable.guid4};private Myadapter mAdapter;private final int AUTO_MSG = 1;private static final int PHOTO_CHANGE_TIME = 2000;private int index = 0;private long exitTime = 0;//Handler导包为android.os.Handlerprivate Handler myhandler = new Handler() {    @Overridepublic void handleMessage(Message msg) {        switch (msg.what) {            case AUTO_MSG:                if (index == images.length) {                    index = 0;                }                vp.setCurrentItem(index++);//收到消息后设置当前要显示的图片myhandler.sendEmptyMessageDelayed(AUTO_MSG, 2000);                break;            default:                break;        }        //  super.handleMessage(msg);}};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //  Toast.makeText(MainActivity.this, "1111", Toast.LENGTH_SHORT).show();    //图片id    //topmain_imags = (ImageView) findViewById(R.id.topmain_imags);vp = (ViewPager) findViewById(R.id.vp);for (int i = 0; i < images.length; i++) {    iv2 = new ImageView(this);    iv2.setImageResource(images[i]);    views.add(iv2);}vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {    @Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {    }    @Overridepublic void onPageSelected(int position) {        iv = (ImageView) MainActivity.this.findViewById(images2[position]);        //iv.setImageResource(R.drawable.go_next);for (int i = 0; i < images2.length; i++) {            if (i != position) {                iv = (ImageView) MainActivity.this.findViewById(images2[i]);                //iv.setImageResource(R.drawable.next_null);}        }    }    @Overridepublic void onPageScrollStateChanged(int state) {    }});myhandler.sendEmptyMessageDelayed(AUTO_MSG, 2000);//轮播图片的适配器vp.setAdapter(new MyImageAdapter());//图片的适配器class MyImageAdapter extends PagerAdapter {    @Overridepublic int getCount() {        return views.size();    }    @Overridepublic Object instantiateItem(ViewGroup container, final int position) {        View v = views.get(position);        v.setOnClickListener(new View.OnClickListener() {            @Overridepublic void onClick(View v) {                int i = position + 1;                if (i == 1) {                    Intent intent = new Intent();                    //给intent设置actionintent.setAction(Intent.ACTION_VIEW);                    //设置数据intent.setData(Uri.parse("http://www.xuexifangfa.com/xuexifangfa/135.html"));                    startActivity(intent);                }                if (i ==2) {                    Intent intent = new Intent();                    //给intent设置actionintent.setAction(Intent.ACTION_VIEW);                    //设置数据intent.setData(Uri.parse("http://www.xuexifangfa.com/xuexifangfa/135.html"));                    startActivity(intent);                }                if (i ==3) {                    Intent intent = new Intent();                    //给intent设置actionintent.setAction(Intent.ACTION_VIEW);                    //设置数据intent.setData(Uri.parse("http://www.xuexila.com/time/497904.html"));                    startActivity(intent);                }                if (i==4) {                    Intent intent = new Intent();                    //给intent设置actionintent.setAction(Intent.ACTION_VIEW);                    //设置数据intent.setData(Uri.parse("http://www.xiaogushi.com/Article/chali/"));                    startActivity(intent);                }               //  Toast.makeText(MainActivity.this, "这是第" + i + "张图片", Toast.LENGTH_SHORT).show();}        });        container.addView(v);        return v;    }    @Overridepublic void destroyItem(ViewGroup container, int position, Object object) {        View v = views.get(position);        container.removeView(v);    }    @Overridepublic boolean isViewFromObject(View view, Object object) {        return view == object;    }}

xml:

<android.support.v4.view.ViewPagerandroid:id="@+id/vp"android:layout_width="match_parent"android:layout_height="80dp"/>

主页面需显示各个科目,考虑到需装许多数据,便采用了ViewPager+Fragment 由于Fragment都是一样的 这里我就只贴一个了,

先贴的是activity:

xml:

<android.support.v4.view.ViewPagerandroid:layout_width="wrap_content"android:layout_height="0dp"android:id="@+id/vp_viewpage_activity"android:layout_weight="1"></android.support.v4.view.ViewPager>

其对应的activity:

  List<Fragment> view = new ArrayList<>();@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //得到viewpager 课程的viewpagervp_viewpage_activity = (ViewPager) findViewById(R.id.vp_viewpage_activity);// 获得对象集合view.add(new ChineseFragment());view.add(new MathFragment());view.add(new EnglishFragment());view.add(new HistoryFragment());view.add(new GeographyFragment());view.add(new LifeFragment());view.add(new ChemistryFragment());view.add(new GovermentFragment());view.add(new PhysicsFragment());//调用适配器vp_viewpage_activity.setAdapter(new Myadapter(getSupportFragmentManager()));//碎片的适配器class Myadapter extends FragmentPagerAdapter {    public Myadapter(FragmentManager fm) {        super(fm);    }    @Overridepublic Fragment getItem(int position) {        return view.get(position);    }    @Overridepublic int getCount() {        return view.size();    }}

碎片activity:

import android.content.Intent;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.example.activity_appui.R;import com.example.activity_appui.com.example.Chinese_famous_write;import com.example.activity_appui.com.example.Chinese_pager_up;import com.example.activity_appui.com.example.Chinese_reader;import com.example.activity_appui.com.example.Chinese_base;public class ChineseFragment extends Fragment {    @Nullable    @Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.activity_chinese, null);            view.findViewById(R.id.tv_chinese).setOnClickListener(new View.OnClickListener() {                @Overridepublic void onClick(View v) {                  //  Toast.makeText(getContext(), "asdasd", Toast.LENGTH_SHORT).show();Intent intent=new Intent(getActivity(), Chinese_base.class);                    startActivity(intent);                }            });        view.findViewById(R.id.tv_chinese2).setOnClickListener(new View.OnClickListener() {            @Overridepublic void onClick(View v) {                Intent intent=new Intent(getActivity(), Chinese_famous_write.class);                startActivity(intent);            }        });        view.findViewById(R.id.tv_chinese3).setOnClickListener(new View.OnClickListener() {            @Overridepublic void onClick(View v) {                Intent intent=new Intent(getActivity(), Chinese_pager_up.class);                startActivity(intent);            }        });        view.findViewById(R.id.tv_chinese4).setOnClickListener(new View.OnClickListener() {            @Overridepublic void onClick(View v) {                Intent intent=new Intent(getActivity(), Chinese_reader.class);                startActivity(intent);            }        });        return view;    }}

xml就不贴了。

这里关于选中变颜色的问题:你只需在values下面的colors.xml里面设置就行了。

然后你开始点单元做题,比如你点击语文做阅读理解题,数据库已经建好了关于语文分类表,你只需要给它设置一个监听事件,然后写个根据类别查询的sql语句就行了。

之后就出现了相应的题目,对于做题,先是需要你选的答案需要与数据库的答案相匹配。如果你的答案正确了便怎样,错了便怎样。像我就是如果选择正确了,便为绿色,错了便为红色。这个的话自己可以写个选择器引用就行了。

这样便能实现一个答题的效果,同时还有一些其他的功能,像一般这样的app都会有各种答题方式,如顺序练习,章节练习,随机练习等等……这些就不一一说了,这个只需修改sql语句,其实现的原理都是一样的。最后想说的是要多勇敢的尝试,不管难不难,都要去尝试,只有尝试了才有资格说难不难,要多给自己机会。还有就是需要思路清晰,把思路清晰了之后再下手,这样效率更高。先写到这,以后有机会再写。

0 0
原创粉丝点击