首页 » 技术分享 » Android 答题App

Android 答题App

 

1.功能介绍

关键技术:SQLite,fragment,ViewFlipper,OnTouchListener

(1)搜索:在搜索框中输入关键词,搜索包含该关键词的题目,并可查看题目详情。


(2)题库:按内容和来源两种分类的题库,可选择题库种的题目进行测试或者练习。其中练习没有计时,没有计分,但能保存当前做题进度;测试计时且计分,最后会显示成绩




(3)错题:按内容和来源两种分类的错题集,可进行练习
(4)收藏:按内容和来源两种分类的收藏,可进行练习
(5)我的记录:记录每次测试的用时和分数

2.搜索功能

【思路】通过关键词,先从SQLite中获取数据cursor,然后在ListView中加载,并设置OnItemClickListener,跳转到对应的题目详情。
【注意】
(1)搜索结果列表,需要设置limit限制列表数量和更多或没有结果的提示信息,以免一次性加载,导致内存溢出或者加载缓慢。
(2)查询关键词的语句是(冒号和空格一定要仔细检查)

"select _id,que from que where que like '%"+text                +"%' or choiceA like '%"+text+"%' or choiceB like'%"+text                +"%' or choiceC like'%"+text+"%' or choiceD ike'%"+text+"%' limit "+limit"
activity_search.xml 搜索界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.lidan.xiao.danquestion.activity.SearchActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar1"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">
    <EditText
        android:id="@+id/sv"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:layout_weight="1"/>
    <ImageView
        android:id="@+id/img_search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/search"
        android:padding="8dp"/>
</LinearLayout>


        </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <com.lidan.xiao.danquestion.view.MyListView
                android:id="@+id/lv_search"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
            <TextView
                android:id="@+id/tv_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/gray"
                android:padding="8dp"
                android:gravity="center"
                android:background="@drawable/bt1"
                android:textSize="16dp"/>
        </LinearLayout>
    </ScrollView>
</LinearLayout>
listitem1.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="wrap_content"
    android:orientation="horizontal"
    android:background="@android:drawable/picture_frame">
    <TextView
        android:id="@+id/tv_item2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:ellipsize="end"
        android:textSize="14sp"/>

</LinearLayout>
MyListView .java
//自定义ListView防止在ScrollView中不能正常显示
public class MyListView extends ListView {
    public MyListView(Context context) {
        super(context);
    }

    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MyListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
public class SearchActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText sv;
    private MyListView lv;
    private TextView tv;
    private ImageView submit;
    private boolean isLv=false;
    private int num=0,limit=10;
    private Cursor cursor;
    private SimpleCursorAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        //ActionBar工具栏设置
        Toolbar toolbar =  findViewById(R.id.toolbar1);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        sv=findViewById(R.id.sv);
        submit=findViewById(R.id.img_search);
        tv=findViewById(R.id.tv_info);
        lv=findViewById(R.id.lv_search);
        submit.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        String text=sv.getText().toString();
        if(!text.isEmpty()){
            searchResult(text);
        }else {
            Toast.makeText(this,"请输入查询内容",Toast.LENGTH_LONG).show();
        }

    }


//查询结果加载
    private void searchResult(final String text) {
          cursor = ToolHelper.loadDB(this,"select _id,que from que where que like '%"+text
                +"%' or choiceA like '%"+text+"%' or choiceB like'%"+text
                +"%' or choiceC like'%"+text+"%' or choiceD like'%"+text+"%' limit "+limit);

        num=cursor.getCount();
        if(num>0) {
            if(!isLv) {//如果lv未创建
                adapter = new SimpleCursorAdapter(this, R.layout.listitem1, cursor,
                        new String[]{"que"}, new int[]{R.id.tv_item2},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
                lv.setAdapter(adapter);
                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        cursor.moveToPosition(position);
                        int select = cursor.getInt(cursor.getColumnIndex("_id"));
                        Intent intent = new Intent(SearchActivity.this, DetailActivity.class);
                        intent.putExtra("qid", select);
                        startActivity(intent);
                    }
                });
                isLv=true;
            }else {//如果lv已经创建,数据改变则重新加载lv
                adapter.changeCursor(cursor);
                adapter.notifyDataSetChanged();
            }
            resultTv(text);

        }else {
            limit=10;
            if(isLv){
                adapter.changeCursor(cursor);
                adapter.notifyDataSetChanged();
                isLv=false;
            }
                tv.setVisibility(View.VISIBLE);
                tv.setText("无查询结果");
        }
    }
//提示信息TextView设置
    private void resultTv(final String text) {
        if(num<limit) {//如果查询结果数小于限制数
            tv.setVisibility(View.GONE);
            limit=10;
        }else if(num>=limit){//如果查询结果数多于限制数
            tv.setText("更多查询数据");
            tv.setVisibility(View.VISIBLE);
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    limit=limit+10;
                    searchResult(text);
                    //Toast.makeText(SearchActivity.this,"limit="+String.valueOf(limit),Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId()==android.R.id.home){//返回
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

}
activity_detail.xml 详情界面
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.lidan.xiao.danquestion.activity.DetailActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <include layout="@layout/layout_top1"/>

        <TextView
            android:id="@+id/tv_que"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textColor="#000000"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_choice"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textColor="@color/colorPrimary" />

        <TextView
            android:id="@+id/tv_answer"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textColor="@color/colorAccent" />

        <TextView
            android:id="@+id/tv_source"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textColor="@color/gray"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/tv_detail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textColor="@color/gray"
            android:textSize="14sp" />
    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_collect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end"
        android:layout_marginRight="8dp"
        android:layout_marginTop="180dp" />

</FrameLayout>
public class DetailActivity extends AppCompatActivity {
    private TextView tv_que, tv_choice, tv_answer, tv_source, tv_detail;
    private FloatingActionButton fabcollect;
    private int qid;
    private boolean tag = false;
    private String kind, type, choice, que, answer, source, detail;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        //ActionBar工具栏设置
        Toolbar toolbar = findViewById(R.id.toolbar1);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        tv_que = findViewById(R.id.tv_que);
        tv_choice = findViewById(R.id.tv_choice);
        tv_answer = findViewById(R.id.tv_answer);
        tv_source = findViewById(R.id.tv_source);
        tv_detail = findViewById(R.id.tv_detail);
        fabcollect = findViewById(R.id.fab_collect);

        Intent intent = getIntent();
        qid = intent.getIntExtra("qid", 0);
        if (qid > 0) {
            loadData();
            initData();
            initCollect();
        }
    }

    private void initCollect() {
        final Cursor cursor = ToolHelper.loadDB(this, "select qid from collection where qid=" + qid);
        if (cursor.getCount() > 0) {
            tag = true;
            fabcollect.setImageResource(R.drawable.star_on);
        } else {
            tag = false;
            fabcollect.setImageResource(R.drawable.star1);
        }
        fabcollect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (tag) {
                    fabcollect.setImageResource(R.drawable.star1);
                    Toast.makeText(DetailActivity.this, "取消收藏", Toast.LENGTH_SHORT).show();
                    ToolHelper.excuteDB(DetailActivity.this, "delete from collection where qid=" + qid);
                } else {
                    fabcollect.setImageResource(R.drawable.star_on);
                    Toast.makeText(DetailActivity.this, "成功收藏", Toast.LENGTH_SHORT).show();
                    ToolHelper.excuteDB(DetailActivity.this, "insert into collection (_id,qid) values (" + (Math.random()*10000) + "," + qid + ")");
                }
            }
        });
    }

    private void loadData() {
        Cursor cursor = ToolHelper.loadDB(this, "select * from que where _id=" + qid);

        cursor.moveToFirst();
        kind = cursor.getString(cursor.getColumnIndex("kind"));
        String choiceA = "A."+cursor.getString(cursor.getColumnIndex("choiceA"));
        String choiceB = "B."+cursor.getString(cursor.getColumnIndex("choiceB"));
        String choiceC = "C."+cursor.getString(cursor.getColumnIndex("choiceC"));
        String choiceD = "D."+cursor.getString(cursor.getColumnIndex("choiceD"));
        StringBuffer sb = new StringBuffer();
        if (choiceA != "null") {
            sb.append(choiceA + "\n");
        }
        if (choiceB != "null") {
            sb.append(choiceB + "\n");
        }
        if (choiceC != "null") {
            sb.append(choiceC + "\n");
        }
        if (choiceD != "null") {
            sb.append(choiceD + "\n");
        }
        choice = sb.toString();
        que = cursor.getString(cursor.getColumnIndex("que"));
        type = cursor.getString(cursor.getColumnIndex("type"));
        answer = cursor.getString(cursor.getColumnIndex("answer"));
        source = cursor.getString(cursor.getColumnIndex("source"));
        detail = cursor.getString(cursor.getColumnIndex("detail"));
    }

    private void initData() {
        setTitle(kind);
        tv_que.setText("(" + type + ")" + que);
        tv_choice.setText(choice);
        tv_answer.setText("【答案】" + answer);
        tv_source.setText("【来源】" + source);
        tv_detail.setText("【解析】" + detail);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home)
            finish();
        return super.onOptionsItemSelected(item);
    }
}

3.测试和练习功能

测试功能中有计时,滑动切换试题,题号选择卡,收藏,错对判断和保存错题,测试结束后会保存考试成绩。
练习功能中有滑动切换试题,题号选择卡,收藏,保存上次进度,错对判断和保存错题。

【滑动切换题目思路】使用AdapterViewFlipper和OnToucherListener实现,首先使用List来存储每个题目view,然后使用BaseAdapter加载到AdapterViewFlipper中,并通过AdapterViewFlipper的OnToucherListener来实现滑动切换题目的指针,切换题目view。

【题号卡思路】使用GridView来显示所有题目号,并标志已答题目,点击题号是返回答题界面结果,并将跳转到选择题目view,其中,viewFlipper不能直接设置当前view的Id来实现跳转,所以可以通过获取当前的题目view的Id,与选择题号相比较,用showPrevious和showNext来实现。

【错对判断思路】当点击提交当前题目的按钮时。先获取checkbox是否被选中,用StringBuffer来拼接自己答案,并存储自己选择的答案到List中来标志为已答题目,然后通过与参考答案对比,看是否加分,如果正确直接跳转到下一题,否则显示正确答案和解析,并存储错题。最后一题完成后会直接显示成绩和考试用时,并保存测试记录。

【注意】
(1)选择测试和练习的题目需显示点击选择后的那项需改变一下,提醒已经选择了该项。
(2)保存错题前一定要检查此题是否已经存在,以免重复。
(3)收藏功能,判断当前题目是否被收藏,并显示,如果未收藏则可以点击按钮,并收藏成功。
(3)保存上次练习进度,直接通过sharedPreference保存当前练习的指针位置。

fragment_question.xml 题库/错题/收藏界面
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="8dp">

        <TextView
            android:id="@+id/top_source"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"/>

        <TextView
            android:id="@+id/top_kind"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"/>

    </LinearLayout>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/tab1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <com.lidan.xiao.danquestion.view.MyListView
                android:id="@+id/lv_que"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <TextView
                android:id="@+id/tv_info1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:padding="8dp" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:layout_gravity="end|bottom"
    android:orientation="vertical">
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_prac"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/test"/>
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab_test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:src="@drawable/exam"/>
</LinearLayout>
</FrameLayout>

@SuppressLint("ValidFragment")
public class QuestionFragment extends Fragment implements View.OnClickListener {
    private int tab;
    private boolean tag = false;
    private View rootView,itemView=null;
    private ListView lv;
    private String table,content;
    public static String field,value;
    private TextView tv1, tv2, info;
    private SimpleCursorAdapter adapter;
    private Cursor cursor;
    private FloatingActionButton fabtest,fabprac;

    @SuppressLint("ValidFragment")
    public QuestionFragment(int tab) {
        this.tab = tab;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_question, container, false);
        tv1 = rootView.findViewById(R.id.top_source);
        tv2 = rootView.findViewById(R.id.top_kind);
        info = rootView.findViewById(R.id.tv_info1);
        info.setText("无内容");
        tv1.setText("来源");
        tv2.setText("分类");
        tv1.setOnClickListener(this);
        tv2.setOnClickListener(this);
        lv = rootView.findViewById(R.id.lv_que);
        fabtest = rootView.findViewById(R.id.fab_test);
        fabtest.setOnClickListener(this);
        fabprac=rootView.findViewById(R.id.fab_prac);
        fabprac.setOnClickListener(this);
        loadData();
        tab1();
        return rootView;
    }
//加载分类题库
    private void tab2() {
        tv1.setTextColor(getResources().getColor(R.color.gray));
        tv2.setTextColor(getResources().getColor(R.color.colorAccent));
        queList("kind");
    }
//加载来源题库
    private void tab1() {
        tv1.setTextColor(getResources().getColor(R.color.colorAccent));
        tv2.setTextColor(getResources().getColor(R.color.gray));
        queList("source");
    }

    private void loadData() {
        switch (tab) {
            case MyTag.QUE://题库
                table = "que";
            content="题库";
                break;
            case MyTag.COLLECT://收藏
                table = "collection ,que where collection.qid=que._id ";
                fabtest.setVisibility(View.GONE);
                content="收藏";
                break;
            case MyTag.WRONG://错题
                table = "wrong,que where wrong.qid=que._id ";
                fabtest.setVisibility(View.GONE);
                content="错题";
                break;
        }
    }
//加载内容到列表
    private void queList(final String type) {
        cursor = ToolHelper.loadDB(getActivity(), "select que._id, que." + type + ",count(que._id) as num from " + table + " group by que." + type+" order by source desc");
        if (cursor.getCount() > 0) {
            if (!tag) {
                adapter = new SimpleCursorAdapter(getActivity(), R.layout.listitem, cursor,
                        new String[]{type, "num"}, new int[]{R.id.tv_item, R.id.tv_item1},
                        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
                lv.setAdapter(adapter);
                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                        TextView tv=view.findViewById(R.id.tv_item);
                        if(itemView!=null) {
                            TextView tv1=itemView.findViewById(R.id.tv_item);
                            tv1.setTextColor(getResources().getColor(R.color.colorPrimaryDark));
                        }
                        tv.setTextColor(getResources().getColor(R.color.colorAccent));
                        itemView=view;
                        field =type;
                        value=cursor.getString(cursor.getColumnIndex(type));
                    }
                });
                info.setVisibility(View.GONE);
            } else {
                adapter.notify();
            }
        } else {
            info.setVisibility(View.VISIBLE);
            info.setText("无记录");
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.fab_test:
                if(itemView!=null)
                askDialog("测试:",2);
                else
                    Toast.makeText(getActivity(),"请选择题目集",Toast.LENGTH_SHORT).show();
                break;
            case R.id.fab_prac:
                if(itemView!=null)
                askDialog("练习:",1);
                else
                Toast.makeText(getActivity(),"请选择题目集",Toast.LENGTH_SHORT).show();
                break;
            case R.id.top_source:
                tab1();
                break;
            case R.id.top_kind:
                tab2();
                break;
        }
    }

    private void askDialog(String str,final int c) {
        AlertDialog.Builder builder=new AlertDialog.Builder(getActivity());
        builder.setMessage(str+"("+content+")"+value+"?");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent;
                if(c==2) {
                    intent = new Intent(getActivity(), QuestionActivity.class);
                }else {
                    intent = new Intent(getActivity(), PracticeActivity.class);
                }
            intent.putExtra("tab",tab);
            startActivity(intent);
            }
        });
        builder.setNegativeButton("取消",null);
        builder.show();
    }
}
activity_question.xml 题库测试界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".activity.QuestionActivity"
    android:orientation="vertical">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar_que"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/AppTheme.PopupOverlay">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="center">
                <ImageView
                    android:id="@+id/img_pre"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:src="@drawable/pre"/>
                <ImageView
                    android:id="@+id/img_card"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:layout_margin="8dp"
                    android:src="@drawable/quecard"/>

            <Chronometer
                android:id="@+id/mytime"
                android:layout_width="80dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textColor="@color/white" />

                <ImageView
                    android:id="@+id/img_collect"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:src="@drawable/star1"
                    android:layout_margin="8dp"/>
                <ImageView
                    android:id="@+id/img_next"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:src="@drawable/next"/>
            </LinearLayout>
        </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>
<include layout="@layout/que_content"/>
</LinearLayout>
queitem.xml题目view
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_que1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp" />
        <CheckBox
            android:id="@+id/cb_choice1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:button="@drawable/cb"
            android:padding="8dp"
            android:textColor="@color/colorPrimary" />
        <CheckBox
            android:id="@+id/cb_choice2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:button="@drawable/cb"
            android:padding="8dp"
            android:textColor="@color/colorPrimary" />
        <CheckBox
            android:id="@+id/cb_choice3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:button="@drawable/cb"
            android:padding="8dp"
            android:textColor="@color/colorPrimary" />
        <CheckBox
            android:id="@+id/cb_choice4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:button="@drawable/cb"
            android:padding="8dp"
            android:textColor="@color/colorPrimary" />
        <TextView
            android:id="@+id/tv_you"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:textColor="@color/colorAccent" />
        <TextView
            android:id="@+id/tv_answer1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:textColor="@color/colorAccent" />

        <TextView
            android:id="@+id/tv_detail1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:textColor="@color/gray" />
    </LinearLayout>
</ScrollView>
//答题Activity

public class QuestionActivity extends AppCompatActivity implements View.OnClickListener {
    private int tab;
    private String table,content;
    private TextView tvTitle, tvScore;
    private Chronometer chronometer;
    private Cursor cursor;
    private boolean isCollect=false,isFirst=false;
    private int num;
    private int score = 0,index=0;
    public static List<String> anList;
    private String source;
    private String qid, type, que, A, B, C, D, answer, detail;
    private ImageView imgPre, imgNext;
    private AdapterViewFlipper vf;
    private BaseAdapter adapter;
    private ProgressBar pb;
    private View root;
    private TextView tvQue, tvDetail, tvAns, tvYou;
    private CheckBox cb1, cb2, cb3, cb4;
    private ImageView imgCollect,imgCard;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_question);
        //ActionBar工具栏设置
        Toolbar toolbar = findViewById(R.id.toolbar_que);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Intent intent=getIntent();
        tab=intent.getIntExtra("tab",1);
        initTable();
        initView();

    }

    private void initTable() {
        switch (tab) {
            case MyTag.QUE://题库
                table = "que";
            content="题库";
                break;
            case MyTag.COLLECT://收藏
                table = "collection ,que where collection.qid=que._id ";
                content="收藏";
            break;
            case MyTag.WRONG://错题
                table = "wrong,que where wrong.qid=que._id ";
                content="错题";
            break;
        }
    }

    @SuppressLint("SetTextI18n")
    private void initView() {
        //初始化收藏按钮
        imgCollect =findViewById(R.id.img_collect);
        imgCollect.setOnClickListener(this);
        //初始化答题卡按钮
        imgCard=findViewById(R.id.img_card);
        imgCard.setOnClickListener(this);
        //初始化计时器
        chronometer = findViewById(R.id.mytime);
        chronometer.setBase(SystemClock.elapsedRealtime());
        chronometer.start();
        chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
            @Override
            public void onChronometerTick(Chronometer chronometer) {
                if (SystemClock.elapsedRealtime() - chronometer.getBase() == 1.5 * 360 * 1000) {
                    Toast.makeText(QuestionActivity.this, "考试时间到", Toast.LENGTH_LONG).show();
                    saveExam();
                }
            }
        });
        //获取题目集关键字
        String field = QuestionFragment.field;
        String value = QuestionFragment.value;
        source = value;
        //设置标题
        tvTitle = findViewById(R.id.tv_title);
        tvTitle.setText(source);
        //获取SQLite数据库中题库数据
        if(tab==MyTag.QUE)
            cursor = ToolHelper.loadDB(this,
                    "select que.* from "+table+" where " + field + "='" + value + "' order by type");
        else
            cursor = ToolHelper.loadDB(this,
                    "select que.* from "+table+" and " + field + "='" + value + "' order by type");
        num = cursor.getCount();
        //答案List初始化
        anList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            anList.add("");
        }

        //设置进度条
        pb = findViewById(R.id.pb);
        pb.setMax(num-1);
        pb.setProgress(0);
        //前后按钮
        imgPre = findViewById(R.id.img_pre);
        imgNext = findViewById(R.id.img_next);
        imgPre.setOnClickListener(this);
        imgNext.setOnClickListener(this);
        //设置初始分数
        tvScore =findViewById(R.id.tv_num);
        tvScore.setText("得分:" + String.valueOf(score )+ "/" +String.valueOf( num));
        //设置ViewFlipper
        vf=findViewById(R.id.vf);
        adapter=new BaseAdapter() {
            @Override
            public int getCount() {
                return num;
            }

            @Override
            public Object getItem(int position) {
                return position;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                index=position;
                createView(position);
                return root;
            }
        };
        vf.setAdapter(adapter);
    }
    //答题卡设置
    private void createView(int pos) {
            root = LayoutInflater.from(QuestionActivity.this).inflate(R.layout.queitem, null);
            tvQue = root.findViewById(R.id.tv_que1);
            cb1 = root.findViewById(R.id.cb_choice1);
            cb2 = root.findViewById(R.id.cb_choice2);
            cb3 = root.findViewById(R.id.cb_choice3);
            cb4 = root.findViewById(R.id.cb_choice4);
            tvAns = root.findViewById(R.id.tv_answer1);
            tvDetail = root.findViewById(R.id.tv_detail1);
            tvYou = root.findViewById(R.id.tv_you);

        //获取数据
        cursor.moveToPosition(pos);
        type = cursor.getString(cursor.getColumnIndex("type"));
        que = cursor.getString(cursor.getColumnIndex("que"));
        A = "A."+cursor.getString(cursor.getColumnIndex("choiceA"));
        B =  "B."+cursor.getString(cursor.getColumnIndex("choiceB"));
        C =  "C."+cursor.getString(cursor.getColumnIndex("choiceC"));
        D =  "D."+cursor.getString(cursor.getColumnIndex("choiceD"));
        answer = cursor.getString(cursor.getColumnIndex("answer"));
        detail = cursor.getString(cursor.getColumnIndex("detail"));
        qid = cursor.getString(cursor.getColumnIndex("_id"));
        //加载内容
        tvQue.setText((pos + 1) + ".(" + type + ")" + que);
        cb1.setText(A);
        cb2.setText(B);
        cb3.setText(C);
        cb4.setText(D);
        cb1.setButtonDrawable(R.drawable.cb);
        cb2.setButtonDrawable(R.drawable.cb);
        cb3.setButtonDrawable(R.drawable.cb);
        cb4.setButtonDrawable(R.drawable.cb);
        cb1.setEnabled(true);
        cb2.setEnabled(true);
        cb3.setEnabled(true);
        cb4.setEnabled(true);
        cb1.setChecked(false);
        cb2.setChecked(false);
       cb3.setChecked(false);
        cb4.setChecked(false);
        tvAns.setText("【正确答案】" + answer);
        tvDetail.setText("【解析】" + detail);
        if (anList.get(pos).equals("")) {
            tvAns.setVisibility(View.GONE);
            tvYou.setVisibility(View.GONE);
            tvDetail.setVisibility(View.GONE);
        } else {
            //已答题设置为不可操作
            disableChecked(pos);
        }
        //设置当前进度
        pb.setProgress(pos);
        //设置是否被收藏
        if(queCollect()){
            isCollect=true;
            imgCollect.setImageResource(R.drawable.star_on);
        }else {
            isCollect=false;
            imgCollect.setImageResource(R.drawable.star1);
        }
        //滑动切换
        root.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                float startX=v.getWidth()/2,endX=v.getWidth()/2,min=100;
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        startX=event.getX();
                    case MotionEvent.ACTION_UP:
                        endX=event.getX();
                        break;
                }
                    if (startX - endX > min) {
                        vf.showNext();
                    }else if (endX - startX > min) {
                        vf.showPrevious();
                }
                return true;
            }
        });

    }

    //判断选择答案对错
    private void isAnswerTrue(int pos) {
        if (cb1.isChecked() || cb2.isChecked() || cb3.isChecked() || cb4.isChecked()) {
            //获取答案
            StringBuffer sb = new StringBuffer();
            if (cb1.isChecked()) sb.append("A");
            if (cb2.isChecked()) sb.append("B");
            if (cb3.isChecked()) sb.append("C");
            if (cb4.isChecked()) sb.append("D");
            String you = sb.toString();
            //保存答案
            anList.set(pos, you);
            //判断对错
            if (you.equals(answer)) {
                moveCorrect();
            } else {
                //错误则保存错题,显示答案
                saveWrong(sb.toString());
                disableChecked(pos);
            }
        }else {
            Toast.makeText(QuestionActivity.this, "请选择答案", Toast.LENGTH_SHORT).show();
        }
    }
    //移除正确题目
    @SuppressLint("SetTextI18n")
    private void moveCorrect() {
        score++;
        tvScore.setText("得分:" + String.valueOf(score )+ "/" +String.valueOf( num));
        vf.showNext();
        int c=ToolHelper.loadDB(this,"select _id from wrong where qid="+qid).getCount();
        if(c>0)
        ToolHelper.excuteDB(this, "delete from wrong where qid=" +qid);
    }

    //已做题不可再做
    private void disableChecked(int pos) {
        tvYou.setText("【你的答案】" + anList.get(pos));
        tvAns.setVisibility(View.VISIBLE);
        tvDetail.setVisibility(View.VISIBLE);
        tvYou.setVisibility(View.VISIBLE);
        if (answer.contains("A")) cb1.setButtonDrawable(R.drawable.cb_right);
        if (answer.contains("B")) cb2.setButtonDrawable(R.drawable.cb_right);
        if (answer.contains("C")) cb3.setButtonDrawable(R.drawable.cb_right);
        if (answer.contains("D")) cb4.setButtonDrawable(R.drawable.cb_right);
        //设置为不可答题
        cb1.setEnabled(false);
        cb2.setEnabled(false);
        cb3.setEnabled(false);
        cb4.setEnabled(false);
    }

    //保存错题
    private void saveWrong(String ans) {
        int c=ToolHelper.loadDB(this,"select _id from wrong where qid="+qid).getCount();
        if(c==0) {
            Date date = new Date();
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String mydate = ft.format(date);
            ToolHelper.excuteDB(this,
                    "insert into wrong (_id,qid,answer,anTime) values (" + String.valueOf(Math.random() * 10000) + "," + qid + ",'" + ans + "','" + mydate + "')");
        }
    }


//判断当前题目是否被收藏
    private boolean queCollect() {
        int c=ToolHelper.loadDB(this,"select _id from collection where qid="+qid).getCount();
        if(c>0) return true;
        else return false;
    }


    //保存考试记录
    private void saveExam() {
        chronometer.stop();
        Date date = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String mytime = chronometer.getText().toString();
        String mydate = ft.format(date);
        String title=source+"\n"+"("+content+")";
        ToolHelper.excuteDB(this, "insert into exam (_id,title,examTime,score,examDate) values (" + String.valueOf(Math.random()*10000)
                +",'" + title + "','" + mytime + "'," + score + ",'" + mydate + "')");
        Intent intent = new Intent(this, ResultActivity.class);
        intent.putExtra("score", score+"/"+num);
        intent.putExtra("time", mytime);
        intent.putExtra("date", mydate);
        intent.putExtra("title",title);
        startActivity(intent);
        finish();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.img_next:
                vf.showNext();
                break;
            case R.id.img_pre:
                vf.showPrevious();
                break;
            case R.id.img_collect://收藏
                if(!isCollect){
                    imgCollect.setImageResource(R.drawable.star_on);
                    ToolHelper.excuteDB(this,"insert into collection (_id,qid) values ("+String.valueOf(Math.random()*10000)+","+qid+")");
                   Toast.makeText(this,"成功收藏",Toast.LENGTH_SHORT).show();
                    isCollect=true;
                }else {
                    imgCollect.setImageResource(R.drawable.star1);
                    ToolHelper.excuteDB(this,"delete from collection where qid="+qid);
                    Toast.makeText(this,"取消收藏",Toast.LENGTH_SHORT).show();
                    isCollect=false;
                }
                break;
            case R.id.img_card:
                Intent intent=new Intent(this,CardActivity.class);
                intent.putExtra("num",num);
                intent.putExtra("from",1);
                startActivityForResult(intent,MyTag.CARD);
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode==MyTag.CARD&&resultCode==MyTag.CARD){
        int select=data.getIntExtra("card",0);
            moveToItem(select);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
//跳转到指定题目
    private void moveToItem(int t) {
        if (t != index) {
            if(t>index) {
               int d= t-index;
                for (int i = 0; i < d + 1; i++)
                    vf.showNext();
            }else if(t<index){
                int p=index-t;
                for (int i = 0; i < p + 1; i++)
                    vf.showPrevious();
            }
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.que, menu);

        return super.onCreateOptionsMenu(menu);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.que_ok://提交答案
                if (index >= num - 1) {
                    if(!isFirst) {
                        isAnswerTrue(index);
                        isFirst = true;
                    }else {
                        AlertDialog.Builder builder = new AlertDialog.Builder(this);
                        builder.setMessage("是否结束测试?");
                        builder.setNegativeButton("取消", null);
                        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                saveExam();
                            }
                        });
                        builder.show();
                    }
                } else {
                    isAnswerTrue(index);
                }
                break;
            case android.R.id.home://返回
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("是否取消测试?");
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        QuestionActivity.this.finish();
                    }
                });
                builder.show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
    }
activity_card.xml 题号卡
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.lidan.xiao.danquestion.activity.CardActivity">
<GridView
    android:id="@+id/gv_card"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:numColumns="5"/>
</LinearLayout>
carditem.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tv_carditem"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:gravity="center"
    android:background="@android:drawable/picture_frame"/>
public class CardActivity extends AppCompatActivity {
private GridView gv;
private int select,num,from;
private TextView selectView=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_card);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        setTitle("选择题号");
        Intent intent=getIntent();
        num=intent.getIntExtra("num",0);
        from=intent.getIntExtra("from",1);
        createCard();
    }

    private void createCard() {
        gv=findViewById(R.id.gv_card);
        BaseAdapter adapter=new BaseAdapter() {
            @Override
            public int getCount() {
                return num;
            }

            @Override
            public Object getItem(int position) {
                return position;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view= LayoutInflater.from(CardActivity.this).inflate(R.layout.carditem,null);
                TextView tv=view.findViewById(R.id.tv_carditem);
                tv.setText(String.valueOf(position+1));
                if(from==1){
                    if(!QuestionActivity.anList.get(position).equals("")){
                        tv.setTextColor(getResources().getColor(R.color.colorAccent));
                    }else {
                        tv.setTextColor(getResources().getColor(R.color.gray));
                    }
                }else if(from==2){
                    if(!PracticeActivity.anList.get(position).equals("")){
                        tv.setTextColor(getResources().getColor(R.color.colorAccent));
                    }else {
                        tv.setTextColor(getResources().getColor(R.color.gray));

                    }
                }
                return view;
            }
        };
        gv.setAdapter(adapter);
        gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if(selectView!=null) {
                    selectView.setTextColor(getResources().getColor(R.color.gray));
                }
                    ((TextView) view).setTextColor(getResources().getColor(R.color.colorAccent));

                selectView= (TextView) view;
                select=position;
                selectCard();
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void selectCard() {
            Intent intent1 = new Intent(this, CardActivity.class);
            intent1.putExtra("card", select);
            //返回数据到前一个Activity
            setResult(MyTag.CARD, intent1);
            finish();
    }
}
activity_result.xml测试成绩
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    tools:context="com.lidan.xiao.danquestion.activity.ResultActivity">

<include layout="@layout/layout_top2"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/picture_frame"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/tv_title1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="8dp"
            android:textColor="@color/colorPrimaryDark"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/tv_score"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="32dp"
            android:layout_marginTop="8dp"
            android:text="得    分:"
            android:textColor="@color/colorAccent"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="32dp"
            android:layout_marginTop="8dp"
            android:text="答题时间:"
            android:textColor="@color/gray"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_date"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="32dp"
            android:layout_marginTop="8dp"
            android:text="提交时间:"
            android:textColor="@color/gray"
            android:textSize="16sp" />
    </LinearLayout>
    <Button
        android:id="@+id/bt_record"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:background="@drawable/bt"
        android:textColor="@color/white"
        android:text="查看考试记录"
        android:layout_margin="8dp"/>
</LinearLayout>


public class ResultActivity extends AppCompatActivity {
    private String title,date,time,score;
    private TextView tvTitle,tvScore,tvDate,tvTime;
    private Button bt;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_result);

        //ActionBar工具栏设置
        Toolbar toolbar = findViewById(R.id.toolbar2);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Intent intent=getIntent();
        title=intent.getStringExtra("title");
        date=intent.getStringExtra("date");
        time=intent.getStringExtra("time");
        score=intent.getStringExtra("score");
        tvTitle=findViewById(R.id.tv_title1);
        tvScore=findViewById(R.id.tv_score);
        tvDate=findViewById(R.id.tv_date);
        tvTime=findViewById(R.id.tv_time);
        tvTitle.setText(title);
        tvScore.append(score);
        tvDate.append(date);
        tvTime.append(time);
        setTitle("测试成绩");
        bt=findViewById(R.id.bt_record);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent1=new Intent(ResultActivity.this,ExamActivity.class);
                startActivity(intent1);
            }
        });
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

public class PracticeActivity extends AppCompatActivity implements View.OnClickListener {
    private int tab;
    private String table,content,from;
    private TextView tvTitle;
    private Cursor cursor;
    private boolean isCollect=false;
    private int num;
    private int index=0,index1;
    public static List<String> anList;
    private String source;
    private String qid, type, que, A, B, C, D, answer, detail;
    private ImageView imgPre, imgNext;
    private AdapterViewFlipper vf;
    private BaseAdapter adapter;
    private ProgressBar pb;
    private View root;
    private TextView tvQue, tvDetail, tvAns;
    private CheckBox cb1, cb2, cb3, cb4;
    private ImageView imgCollect,imgCard;
    private SharedPreferences sp;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_question);//与测试界面为同一个界面
        //ActionBar工具栏设置
        Toolbar toolbar = findViewById(R.id.toolbar_que);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        sp=getPreferences(Context.MODE_PRIVATE);
        Intent intent=getIntent();
        tab=intent.getIntExtra("tab",1);
        initTable();
        initView();

    }

    private void initTable() {
        switch (tab) {
            case MyTag.QUE://题库
                table = "que";
                content="题库";
                from="que";
                break;
            case MyTag.COLLECT://收藏
                table = "collection ,que where collection.qid=que._id ";
                content="收藏";
                from="collect";
                break;
            case MyTag.WRONG://错题
                table = "wrong,que where wrong.qid=que._id ";
                content="错题";
                from="wrong";
                break;
        }
        getProgress(from);
    }

    private void getProgress(String t) {
        index1=sp.getInt(t+"index",0);
    }

    private void saveProgess(String t) {
        SharedPreferences.Editor editor=sp.edit();
        editor.putInt(t+"index",index);
        editor.commit();
    }

    @SuppressLint("SetTextI18n")
    private void initView() {
        //初始化收藏按钮
        imgCollect =findViewById(R.id.img_collect);
        imgCollect.setOnClickListener(this);
        //初始化答题卡按钮
        imgCard=findViewById(R.id.img_card);
        imgCard.setOnClickListener(this);

        findViewById(R.id.mytime).setVisibility(View.GONE);

        //获取题目集关键字
        String field = QuestionFragment.field;
        String value = QuestionFragment.value;
        source = value;
        //设置标题
        tvTitle = findViewById(R.id.tv_title);
        tvTitle.setText(source);
        //获取SQLite数据库中题库数据
        if(tab==MyTag.QUE)
            cursor = ToolHelper.loadDB(this,
                    "select que.* from "+table+" where " + field + "='" + value + "' order by type");
        else
            cursor = ToolHelper.loadDB(this,
                    "select que.* from "+table+" and " + field + "='" + value + "' order by type");
        num = cursor.getCount();
        //答案List初始化
        anList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            anList.add("");
        }

        //设置进度条
        pb = findViewById(R.id.pb);
        pb.setMax(num-1);
        pb.setProgress(0);
        //前后按钮
        imgPre = findViewById(R.id.img_pre);
        imgNext = findViewById(R.id.img_next);
        imgPre.setOnClickListener(this);
        imgNext.setOnClickListener(this);
        //设置ViewFlipper
        vf=findViewById(R.id.vf);
        adapter=new BaseAdapter() {
            @Override
            public int getCount() {
                return num;
            }

            @Override
            public Object getItem(int position) {
                return position;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                index=position;
                createView(position);
                return root;
            }
        };
        vf.setAdapter(adapter);
        moveToItem(index1);
    }
    //答题卡设置
    private void createView(int pos) {
        root = LayoutInflater.from(PracticeActivity.this).inflate(R.layout.queitem, null);
        tvQue = root.findViewById(R.id.tv_que1);
        cb1 = root.findViewById(R.id.cb_choice1);
        cb2 = root.findViewById(R.id.cb_choice2);
        cb3 = root.findViewById(R.id.cb_choice3);
        cb4 = root.findViewById(R.id.cb_choice4);
        tvAns = root.findViewById(R.id.tv_answer1);
        tvDetail = root.findViewById(R.id.tv_detail1);

        //获取数据
        cursor.moveToPosition(pos);
        type = cursor.getString(cursor.getColumnIndex("type"));
        que = cursor.getString(cursor.getColumnIndex("que"));
        A = "A."+cursor.getString(cursor.getColumnIndex("choiceA"));
        B =  "B."+cursor.getString(cursor.getColumnIndex("choiceB"));
        C =  "C."+cursor.getString(cursor.getColumnIndex("choiceC"));
        D =  "D."+cursor.getString(cursor.getColumnIndex("choiceD"));
        answer = cursor.getString(cursor.getColumnIndex("answer"));
        detail = cursor.getString(cursor.getColumnIndex("detail"));
        qid = cursor.getString(cursor.getColumnIndex("_id"));
        //加载内容
        tvQue.setText((pos + 1) + ".(" + type + ")" + que);
        cb1.setText(A);
        cb2.setText(B);
        cb3.setText(C);
        cb4.setText(D);
        cb1.setButtonDrawable(R.drawable.cb);
        cb2.setButtonDrawable(R.drawable.cb);
        cb3.setButtonDrawable(R.drawable.cb);
        cb4.setButtonDrawable(R.drawable.cb);
        cb1.setEnabled(true);
        cb2.setEnabled(true);
        cb3.setEnabled(true);
        cb4.setEnabled(true);
        cb1.setChecked(false);
        cb2.setChecked(false);
        cb3.setChecked(false);
        cb4.setChecked(false);
        tvAns.setText("【正确答案】" + answer);
        tvDetail.setText("【解析】" + detail);
        if (anList.get(pos).equals("")) {
            tvAns.setVisibility(View.GONE);
            tvDetail.setVisibility(View.GONE);
        } else {
            //已答题设置为不可操作
            disableChecked(pos);
        }
        //设置当前进度
        pb.setProgress(pos);
        //设置是否被收藏
        if(queCollect()){
            isCollect=true;
            imgCollect.setImageResource(R.drawable.star_on);
        }else {
            isCollect=false;
            imgCollect.setImageResource(R.drawable.star1);
        }
        //滑动切换
        root.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                float startX=v.getWidth()/2,endX=v.getWidth()/2,min=100;
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        startX=event.getX();
                    case MotionEvent.ACTION_UP:
                        endX=event.getX();
                        break;
                }
                if (startX - endX > min) {
                    vf.showNext();
                }else if (endX - startX > min) {
                    vf.showPrevious();
                }
                return true;
            }
        });

    }

    //判断选择答案对错
    private void isAnswerTrue(int pos) {
        if (cb1.isChecked() || cb2.isChecked() || cb3.isChecked() || cb4.isChecked()) {
            //获取答案
            StringBuffer sb = new StringBuffer();
            if (cb1.isChecked()) sb.append("A");
            if (cb2.isChecked()) sb.append("B");
            if (cb3.isChecked()) sb.append("C");
            if (cb4.isChecked()) sb.append("D");
            String you = sb.toString();
            //保存答案
            anList.set(pos, you);
            //判断对错
            if (you.equals(answer)) {
                moveCorrect();
            } else {
                //错误则保存错题,显示答案
                saveWrong(sb.toString());
                disableChecked(pos);
            }
        }else {
            Toast.makeText(PracticeActivity.this, "请选择答案", Toast.LENGTH_SHORT).show();
        }
    }
    //移除正确题目
    @SuppressLint("SetTextI18n")
    private void moveCorrect() {
        vf.showNext();
        int c=ToolHelper.loadDB(this,"select _id from wrong where qid="+qid).getCount();
        if(c>0)
            ToolHelper.excuteDB(this, "delete from wrong where qid=" +qid);
    }

    //已做题不可再做
    private void disableChecked(int pos) {
        tvAns.setVisibility(View.VISIBLE);
        tvDetail.setVisibility(View.VISIBLE);

        if (answer.contains("A")) cb1.setButtonDrawable(R.drawable.cb_right);
        if (answer.contains("B")) cb2.setButtonDrawable(R.drawable.cb_right);
        if (answer.contains("C")) cb3.setButtonDrawable(R.drawable.cb_right);
        if (answer.contains("D")) cb4.setButtonDrawable(R.drawable.cb_right);
    }

    //保存错题
    private void saveWrong(String ans) {
        int c=ToolHelper.loadDB(this,"select _id from wrong where qid="+qid).getCount();
        if(c==0) {
            Date date = new Date();
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String mydate = ft.format(date);
            ToolHelper.excuteDB(this,
                    "insert into wrong (_id,qid,answer,anTime) values (" + String.valueOf(Math.random() * 10000) + "," + qid + ",'" + ans + "','" + mydate + "')");
        }
    }

    //判断当前题目是否被收藏
    private boolean queCollect() {
        int c=ToolHelper.loadDB(this,"select _id from collection where qid="+qid).getCount();
        if(c>0) return true;
        else return false;
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.que, menu);

        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.que_ok://提交答案
                    isAnswerTrue(index);
                break;
            case android.R.id.home://返回
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("是否取消练习?");
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        saveProgess(from);
                        PracticeActivity.this.finish();
                    }
                });
                builder.show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.img_next:
                vf.showNext();
                break;
            case R.id.img_pre:
                vf.showPrevious();
                break;
            case R.id.img_collect://收藏
                if(!isCollect){
                    imgCollect.setImageResource(R.drawable.star_on);
                    ToolHelper.excuteDB(this,"insert into collection (_id,qid) values ("+String.valueOf(Math.random()*10000)+","+qid+")");
                    Toast.makeText(this,"成功收藏",Toast.LENGTH_SHORT).show();
                    isCollect=true;
                }else {
                    imgCollect.setImageResource(R.drawable.star1);
                    ToolHelper.excuteDB(this,"delete from collection where qid="+qid);
                    Toast.makeText(this,"取消收藏",Toast.LENGTH_SHORT).show();
                    isCollect=false;
                }
                break;
            case R.id.img_card:
                Intent intent=new Intent(this,CardActivity.class);
                intent.putExtra("num",num);
                intent.putExtra("from",2);
                startActivityForResult(intent,MyTag.CARD);
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode==MyTag.CARD&&resultCode==MyTag.CARD){
            int select=data.getIntExtra("card",0);
            moveToItem(select);

        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void moveToItem(int t) {
        if (t != index) {
            if(t>index) {
                int d= t-index;
                for (int i = 0; i < d; i++)
                    vf.showNext();
            }else if(t<index){
                int p=index-t;
                for (int i = 0; i < p; i++)
                    vf.showPrevious();
            }
        }
    }
}

4.项目GitHut地址

https://github.com/xiaolidan00/question

转载自原文链接, 如需删除请联系管理员。

原文链接:Android 答题App,转载请注明来源!

0