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.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/AppTheme.AppBarOverlay"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar1"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay">
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:orientation="horizontal"><EditTextandroid:id="@+id/sv"android:layout_width="0dp"android:layout_height="wrap_content"android:textColor="@color/white"android:layout_weight="1"/><ImageViewandroid: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><ScrollViewandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><com.lidan.xiao.danquestion.view.MyListViewandroid:id="@+id/lv_search"android:layout_width="match_parent"android:layout_height="wrap_content"/><TextViewandroid: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"?>
<LinearLayoutxmlns: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"><TextViewandroid: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);}@Overrideprotected 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;@Overridepublic 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);}@Overridepublic 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() {@Overridepublic 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已经创建,数据改变则重新加载lvadapter.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() {@Overridepublic void onClick(View v) {limit=limit+10;searchResult(text);//Toast.makeText(SearchActivity.this,"limit="+String.valueOf(limit),Toast.LENGTH_SHORT).show();}});}}@Overridepublic 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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><include layout="@layout/layout_top1"/><TextViewandroid:id="@+id/tv_que"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:textColor="#000000"android:textSize="16sp" /><TextViewandroid:id="@+id/tv_choice"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:textColor="@color/colorPrimary" /><TextViewandroid:id="@+id/tv_answer"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:textColor="@color/colorAccent" /><TextViewandroid: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" /><TextViewandroid: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.FloatingActionButtonandroid: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;@Overridepublic 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() {@Overridepublic 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);}@Overridepublic 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">
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:padding="8dp"><TextViewandroid:id="@+id/top_source"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"/><TextViewandroid:id="@+id/top_kind"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"/></LinearLayout><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:id="@+id/tab1"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><com.lidan.xiao.danquestion.view.MyListViewandroid:id="@+id/lv_que"android:layout_width="match_parent"android:layout_height="match_parent" /><TextViewandroid:id="@+id/tv_info1"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:padding="8dp" /></LinearLayout></ScrollView>
</LinearLayout>
<LinearLayoutandroid: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.FloatingActionButtonandroid:id="@+id/fab_prac"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/test"/><android.support.design.widget.FloatingActionButtonandroid: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@Overridepublic 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() {@Overridepublic 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("无记录");}}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.fab_test:if(itemView!=null)askDialog("测试:",2);elseToast.makeText(getActivity(),"请选择题目集",Toast.LENGTH_SHORT).show();break;case R.id.fab_prac:if(itemView!=null)askDialog("练习:",1);elseToast.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() {@Overridepublic 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.AppBarLayoutandroid: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.Toolbarandroid:id="@+id/toolbar_que"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"app:layout_collapseMode="pin"app:popupTheme="@style/AppTheme.PopupOverlay"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><ImageViewandroid:id="@+id/img_pre"android:layout_width="32dp"android:layout_height="32dp"android:src="@drawable/pre"/><ImageViewandroid:id="@+id/img_card"android:layout_width="32dp"android:layout_height="32dp"android:layout_margin="8dp"android:src="@drawable/quecard"/><Chronometerandroid:id="@+id/mytime"android:layout_width="80dp"android:layout_height="wrap_content"android:gravity="center"android:textColor="@color/white" /><ImageViewandroid:id="@+id/img_collect"android:layout_width="32dp"android:layout_height="32dp"android:src="@drawable/star1"android:layout_margin="8dp"/><ImageViewandroid: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv_que1"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp" /><CheckBoxandroid: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" /><CheckBoxandroid: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" /><CheckBoxandroid: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" /><CheckBoxandroid: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" /><TextViewandroid:id="@+id/tv_you"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"android:textColor="@color/colorAccent" /><TextViewandroid:id="@+id/tv_answer1"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"android:textColor="@color/colorAccent" /><TextViewandroid:id="@+id/tv_detail1"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"android:textColor="@color/gray" /></LinearLayout>
</ScrollView>
//答题Activitypublic 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;@Overrideprotected 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() {@Overridepublic 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");elsecursor = 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));//设置ViewFlippervf=findViewById(R.id.vf);adapter=new BaseAdapter() {@Overridepublic int getCount() {return num;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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() {@Overridepublic 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();}@Overridepublic 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;}}@Overrideprotected 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();}}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.que, menu);return super.onCreateOptionsMenu(menu);}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {}});builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic 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">
<GridViewandroid: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"?>
<TextViewxmlns: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;@Overrideprotected 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() {@Overridepublic int getCount() {return num;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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() {@Overridepublic 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();}});}@Overridepublic 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);//返回数据到前一个ActivitysetResult(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"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:drawable/picture_frame"android:orientation="vertical"android:padding="16dp"><TextViewandroid: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" /><TextViewandroid: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" /><TextViewandroid: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" /><TextViewandroid: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><Buttonandroid: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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {Intent intent1=new Intent(ResultActivity.this,ExamActivity.class);startActivity(intent1);}});}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()){case android.R.id.home:finish();break;}return super.onOptionsItemSelected(item);}
}

4.项目GitHut地址

https://github.com/xiaolidan00/question

微信关注 “安卓集中营”,获取更多

或者扫码关注

一起共同学习探讨

Android 答题相关推荐

  1. Android答题计时的代码,Android答题倒计时

    Android答题倒计时:讲一下我在做一个答题APP时涉及到倒计时时遇到的一个问题吧.碎片+CountDownTimer组成的一个答题,其中遇到的一个问题就是.这个题的倒计时在你手动滑动下一个题的时候 ...

  2. Android答题 通过RecyclerView显示题目和选项并提交答案

    最近需要实现一个答题功能,参考网上很多方法都是ViewPage实现的,出于各种原因我并不是很想用ViewPage 于是决定研究怎么用RecyclerView实现 但是踩了各种坑,大概也知道为什么几乎没 ...

  3. Android答题app

    当我们第一次安装软件打开时,进入的是导航页面,导航面采用的是Activity+fragment实现侧滑导航页的效果,而以后打开进入的是启动页面此效果采用的是SharedPreferences,实现代码 ...

  4. Android 实现答题器功能(通过手势实现翻页效果)

    Android 实现答题器功能(通过手势实现翻页效果) 1.问题描述 Android答题器的实现主要使用了ViewFilpper和GestureDetector来实现. 2.实现思路 把Activit ...

  5. Android 实现答题器功能(通过手势实现翻页效果)...

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/51305933 Android 实现答题器功能 ...

  6. Android应用【世界杯知识答题】的界面设计经验

    一.应用简介 [世界杯知识答题]Y球迷的贴心手机补品应用 您对世界杯的相关知识了解有多少,答对足够多的题目就可以进入下一关喔,2010年南非世界杯正在进行,让我们一起答题闯关吧. 支持Android ...

  7. android开发答题app,Android APP编写简单答题器

    本文为大家分享了Android APP编写的简单答题器,此答题器可以通过Next按钮选择下一题,新写题目的类Question,有两个成员变量. java代码: package com.android. ...

  8. Android 每日答题

    文章目录 一.案例演示 二.页面布局 1.activity_question.xml 2.fragment_radio_button.xml 3.fragment_chex_box.xml 三.功能实 ...

  9. android 简易我的积分页面、答题页面的设计

    一.我的积分页面设计 1.页面布局文件 activity_my_points.xml 代码如下: <?xml version="1.0" encoding="utf ...

最新文章

  1. java远程桌面图片压缩问题_java用Socket实现的远程桌面浏览 内存溢出问题
  2. 三、css 和 js 的装载与执行
  3. 实现当前目录下开启CMD
  4. unity消息队列判断字符串相等有错误_Python3十大经典错误及解决办法
  5. python sys模块_Python 基础(二十):sys 模块
  6. Python高级——property属性
  7. 下半年值得关注的新机和科技趋势
  8. ssl证书不可信 群晖_上海云盾 CDN 网站 SSL 证书过期更新不生效问题排查和解决...
  9. Element源码系列——搭建Karma测试环境及Eslint语法检测
  10. JDBC数据库驱动的下载、安装与连接
  11. Zemax操作24--高斯光束的聚焦和传播
  12. (Select)解决:Element-ui 中 Select 选择器下拉框样式及输入框样式的修改问题(背景色透明与悬停背景色变化与下拉框边距变化等操作)
  13. 信息安全-网络安全应急响应技术原理与应用(一)
  14. 计算机设备管理器没有WDS,hp 1136 电脑重启后 自动脱机 ,打印机服务也开起来,要把驱动删除掉,重新安装驱动才可以...
  15. 微信小程序 转发 分享功能
  16. 通过计算机英语怎么说,通过英文怎么说
  17. P2141 [NOIP2014 普及组] 珠心算测验
  18. librosa提取mel_fbank
  19. VFIO代码分析(3)VFIO-PCI驱动2
  20. 设正整数n的十进制表示为n=ak……a1a0(0=ai=9,0=i=k,ak!=0),n的个位为起始数字的数字的正负交错之和T(n)=a0+a1+……+(-1)kak,证明:11|n的充分必要...

热门文章

  1. Echarts 柱状图渐变色设置
  2. 中国存储器“3+1”版图初现 行业要再跑5年马拉松
  3. 【可爱甜美圆嘟嘟的孩子壁纸】
  4. unity下图灵机器人的使用
  5. Dbg2Excel_Word
  6. 【HMS core】【Wallet Kit】【解决方案】华为钱包的客户端示例代码为何无法运行
  7. 质因子分解算法c语言prime,分解质因数的算法
  8. 从两句偈语开始写的一首诗《看花》,以及创造思路、过程
  9. django+javascrpt+python实现私有云盘代码
  10. WP免费主题,wordpress免费主题,WP建站主题