安卓 仿学习app项目

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

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 {

    @Override
protected 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秒
@Override
public 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; //装载导航小圆点
@Override
protected 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(){

            @Override
public int getCount() {
                return vList.size();
            }

            @Override
public void destroyItem(ViewGroup container, int position, Object object) {
                // super.destroyItem(container, position, object);
container.removeView((View) vList.get(position));
            }

            @Override
public Object instantiateItem(ViewGroup container, int position) {
                container.addView((View) vList.get(position));
                return vList.get(position);
            }

            @Override
public 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));
            else
pointImgViews[i].setImageDrawable(getResources().getDrawable(
                        R.drawable.i3));
            // 将imageviews添加到小圆点视图组
pointGroup.addView(pointImgViews[i]);
        }
    }

    //添加监听器,将相应页面的小圆点设置为选中状态
private void setAdapterForViewPager(){
        vPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()

        {
            @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
public 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));
                }
            }

            @Override
public 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.ViewPager
android:id="@+id/navigation_vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

    <LinearLayout
android: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;

    @Override
protected 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 {
        @Override
public 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">

    <ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/g_1"
android:id="@+id/splash_img"
android:scaleType="fitXY"
/>

    <TextView
android: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="倒计时"
/>

    <TextView
android: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};
//定义一个全局变量 当前的变量为0
int 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.Handler
private Handler myhandler = new Handler() {
    @Override
public 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);
}
};



@Override
protected 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() {
    @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
public 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);
}
        }
    }

    @Override
public void onPageScrollStateChanged(int state) {

    }
});
myhandler.sendEmptyMessageDelayed(AUTO_MSG, 2000);

//轮播图片的适配器
vp.setAdapter(new MyImageAdapter());

//图片的适配器
class MyImageAdapter extends PagerAdapter {
    @Override
public int getCount() {
        return views.size();
    }
    @Override
public Object instantiateItem(ViewGroup container, final int position) {
        View v = views.get(position);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
public void onClick(View v) {
                int i = position + 1;
                if (i == 1) {
                    Intent intent = new Intent();
                    //给intent设置action
intent.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设置action
intent.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设置action
intent.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设置action
intent.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;
    }

    @Override
public void destroyItem(ViewGroup container, int position, Object object) {
        View v = views.get(position);
        container.removeView(v);
    }

    @Override
public boolean isViewFromObject(View view, Object object) {

        return view == object;
    }
}



xml:

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

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

先贴的是activity:

xml:

<android.support.v4.view.ViewPager
android: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<>();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //得到viewpager 课程的viewpager
vp_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);
    }

    @Override
public Fragment getItem(int position) {
        return view.get(position);
    }

    @Override
public 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
    @Override
public 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() {
                @Override
public 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() {
            @Override
public 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() {
            @Override
public 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() {
            @Override
public void onClick(View v) {
                Intent intent=new Intent(getActivity(), Chinese_reader.class);
                startActivity(intent);
            }
        });
        return view;
    }
}

xml就不贴了。

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

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

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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值