From 5c32cb754ba6abeb264fa96e725614126d733c40 Mon Sep 17 00:00:00 2001 From: PrismRealm Date: Sun, 21 Apr 2019 01:40:43 +0800 Subject: [PATCH] Update all --- .project | 17 + .settings/org.eclipse.buildship.core.prefs | 2 + app/build.gradle | 27 + app/proguard-rules.pro | 17 + .../englishhelper/ApplicationTest.java | 13 + app/src/main/AndroidManifest.xml | 46 + app/src/main/appicon-web.png | Bin 0 -> 46254 bytes app/src/main/assets/Test.txt | 1 + app/src/main/assets/Words.txt | 2826 +++++++++++++++++ app/src/main/assets/word_packages.txt | 15 + .../englishhelper/ActListOfWordPackage.java | 99 + .../englishhelper/ActSearchWord.java | 270 ++ .../englishhelper/ActWordPackages.java | 44 + .../englishhelper/MainActivity.java | 242 ++ .../englishhelper/access/FTPThread.java | 25 + .../englishhelper/access/TheManager.java | 29 + .../englishhelper/access/WordInfo.java | 108 + .../act_4selections/Act4Selection.java | 250 ++ .../act_4selections/Act4SelectionResult.java | 95 + .../act_4selections/ActMultipleChoice.java | 356 +++ .../act_allwords/ActAddingGroup.java | 49 + .../act_allwords/ActAllVoca.java | 55 + .../act_allwords/ActEditingGroup.java | 124 + .../act_allwords/ActGrouping.java | 170 + .../act_allwords/ActPieceVoca.java | 92 + .../act_allwords/ActWordInfo.java | 122 + .../act_memory/ActMemoryPractice.java | 392 +++ .../act_memory/ActMemoryResult.java | 90 + .../act_memory/ActMemorySetting.java | 192 ++ .../act_spelling/ActSpellingExamine.java | 215 ++ .../act_spelling/ActSpellingResult.java | 80 + .../act_spelling/ActSpellingSetting.java | 164 + app/src/main/res/Test.txt | 1 + app/src/main/res/drawable/drawable.xml | 4 + app/src/main/res/drawable/icon.png | Bin 0 -> 2158 bytes app/src/main/res/drawable/redngreen.png | Bin 0 -> 10550 bytes .../res/layout/activity_act4_selection.xml | 192 ++ .../layout/activity_act4_selection_result.xml | 131 + .../res/layout/activity_act_adding_group.xml | 61 + .../main/res/layout/activity_act_all_voca.xml | 88 + .../res/layout/activity_act_editing_group.xml | 73 + .../main/res/layout/activity_act_grouping.xml | 80 + .../activity_act_list_of_word_package.xml | 65 + .../layout/activity_act_memory_practice.xml | 109 + .../res/layout/activity_act_memory_result.xml | 77 + .../layout/activity_act_memory_setting.xml | 199 ++ .../layout/activity_act_multiple_choice.xml | 124 + .../res/layout/activity_act_piece_voca.xml | 43 + .../res/layout/activity_act_search_word.xml | 135 + .../layout/activity_act_spelling_examine.xml | 265 ++ .../layout/activity_act_spelling_result.xml | 148 + .../layout/activity_act_spelling_setting.xml | 190 ++ .../res/layout/activity_act_word_info.xml | 216 ++ .../res/layout/activity_act_word_packages.xml | 65 + app/src/main/res/layout/activity_main.xml | 125 + app/src/main/res/mipmap-hdpi/appicon.png | Bin 0 -> 2769 bytes app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes app/src/main/res/mipmap-mdpi/appicon.png | Bin 0 -> 1693 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes app/src/main/res/mipmap-xhdpi/appicon.png | Bin 0 -> 3968 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes app/src/main/res/mipmap-xxhdpi/appicon.png | Bin 0 -> 6617 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes app/src/main/res/mipmap-xxxhdpi/appicon.png | Bin 0 -> 9997 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10486 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings.xml | 31 + app/src/main/res/values/styles.xml | 11 + .../englishhelper/ExampleUnitTest.java | 15 + build.gradle | 23 + gradle.properties | 18 + gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 + gradlew.bat | 90 + settings.gradle | 1 + 77 files changed, 8990 insertions(+) create mode 100644 .project create mode 100644 .settings/org.eclipse.buildship.core.prefs create mode 100755 app/build.gradle create mode 100755 app/proguard-rules.pro create mode 100755 app/src/androidTest/java/com/example/leeyuanair/englishhelper/ApplicationTest.java create mode 100755 app/src/main/AndroidManifest.xml create mode 100755 app/src/main/appicon-web.png create mode 100755 app/src/main/assets/Test.txt create mode 100755 app/src/main/assets/Words.txt create mode 100755 app/src/main/assets/word_packages.txt create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/ActListOfWordPackage.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/ActSearchWord.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/ActWordPackages.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/MainActivity.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/access/FTPThread.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/access/TheManager.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/access/WordInfo.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/Act4Selection.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/Act4SelectionResult.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/ActMultipleChoice.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAddingGroup.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAllVoca.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActEditingGroup.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActGrouping.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActPieceVoca.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActWordInfo.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemoryPractice.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemoryResult.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemorySetting.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingExamine.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingResult.java create mode 100755 app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingSetting.java create mode 100755 app/src/main/res/Test.txt create mode 100755 app/src/main/res/drawable/drawable.xml create mode 100755 app/src/main/res/drawable/icon.png create mode 100755 app/src/main/res/drawable/redngreen.png create mode 100755 app/src/main/res/layout/activity_act4_selection.xml create mode 100755 app/src/main/res/layout/activity_act4_selection_result.xml create mode 100755 app/src/main/res/layout/activity_act_adding_group.xml create mode 100755 app/src/main/res/layout/activity_act_all_voca.xml create mode 100755 app/src/main/res/layout/activity_act_editing_group.xml create mode 100755 app/src/main/res/layout/activity_act_grouping.xml create mode 100755 app/src/main/res/layout/activity_act_list_of_word_package.xml create mode 100755 app/src/main/res/layout/activity_act_memory_practice.xml create mode 100755 app/src/main/res/layout/activity_act_memory_result.xml create mode 100755 app/src/main/res/layout/activity_act_memory_setting.xml create mode 100755 app/src/main/res/layout/activity_act_multiple_choice.xml create mode 100755 app/src/main/res/layout/activity_act_piece_voca.xml create mode 100755 app/src/main/res/layout/activity_act_search_word.xml create mode 100755 app/src/main/res/layout/activity_act_spelling_examine.xml create mode 100755 app/src/main/res/layout/activity_act_spelling_result.xml create mode 100755 app/src/main/res/layout/activity_act_spelling_setting.xml create mode 100755 app/src/main/res/layout/activity_act_word_info.xml create mode 100755 app/src/main/res/layout/activity_act_word_packages.xml create mode 100755 app/src/main/res/layout/activity_main.xml create mode 100755 app/src/main/res/mipmap-hdpi/appicon.png create mode 100755 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-mdpi/appicon.png create mode 100755 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xhdpi/appicon.png create mode 100755 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxhdpi/appicon.png create mode 100755 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxxhdpi/appicon.png create mode 100755 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100755 app/src/main/res/values-w820dp/dimens.xml create mode 100755 app/src/main/res/values/colors.xml create mode 100755 app/src/main/res/values/dimens.xml create mode 100755 app/src/main/res/values/strings.xml create mode 100755 app/src/main/res/values/styles.xml create mode 100755 app/src/test/java/com/example/leeyuanair/englishhelper/ExampleUnitTest.java create mode 100755 build.gradle create mode 100755 gradle.properties create mode 100755 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100755 gradlew.bat create mode 100755 settings.gradle diff --git a/.project b/.project new file mode 100644 index 0000000..f646a9d --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + EnglishHelper + Project EnglishHelper created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..e889521 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/app/build.gradle b/app/build.gradle new file mode 100755 index 0000000..a2d3404 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.2" + + defaultConfig { + applicationId "com.example.leeyuanair.englishhelper" + minSdkVersion 16 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:23.1.1' + compile files('libs/apache-commons-net.jar') +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100755 index 0000000..1ab18bb --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/example/leeyuanair/englishhelper/ApplicationTest.java b/app/src/androidTest/java/com/example/leeyuanair/englishhelper/ApplicationTest.java new file mode 100755 index 0000000..3a159b0 --- /dev/null +++ b/app/src/androidTest/java/com/example/leeyuanair/englishhelper/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.example.leeyuanair.englishhelper; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100755 index 0000000..21f69e8 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:screenOrientation="portrait" + + + + diff --git a/app/src/main/appicon-web.png b/app/src/main/appicon-web.png new file mode 100755 index 0000000000000000000000000000000000000000..e1fd0e02f424dba5a4f089f4f391b0a8292f4246 GIT binary patch literal 46254 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 u#YSl#o_z1u information; + //TextView文字標籤元件 + TextView lblWordPackageExplanation; + //ListView清單元件 + ListView lstWordPackage; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_list_of_word_package); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + //連結文字標籤元件 + lblWordPackageExplanation = (TextView) findViewById(R.id.lblWordPackageExplanation); + lstWordPackage = (ListView) findViewById(R.id.lstWordPackage); + lstWordPackage.setOnItemClickListener(this); + //讀取上一層的資料 + int index = getIntent().getExtras().getInt("Index"); + setTitle("單字包裹 - " + MainActivity.WORD_PACKAGES_NAMES.get(index)); + //取得使用者所選的 + information = MainActivity.WORD_PACKAGES.get(MainActivity.WORD_PACKAGES_NAMES.get(index)); + ArrayAdapter wordsArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1); + lblWordPackageExplanation.setText(information.get(0)); + //逐次尋找該字資源並映到清單上 + int power, point_power; + //設定詞性取得的優先權 + switch (information.get(1)) { + case "n": + power = 0; + break; + case "a": + power = 1; + break; + case "v": + power = 2; + break; + case "adv": + power = 3; + break; + case "prep": + power = 4; + break; + default: + power = 0; + break; + } + //pOS = Part Of Speech,字串陣列,表示儲存某單字的所有詞性中文意思 + String[] pOS; + //循序取得資訊並存路wordsArrayAdapter裡 + for (int i = 2; i < information.size(); i++) { + pOS = MainActivity.ALL_WORDS.get(information.get(i)); + point_power = power; + while (pOS[point_power] == null || pOS[point_power].equals("")) + point_power++; + wordsArrayAdapter.add(information.get(i) +" "+ Number2pOS(point_power) + " " + pOS[point_power]); + } + lstWordPackage.setAdapter(wordsArrayAdapter); + } + //函式 - 數值轉詞性縮寫 + String Number2pOS(int number){ + switch (number){ + case 0: return "(n.)"; + case 1: return "(adj.)"; + case 2: return "(v.)"; + case 3: return "(adv.)"; + case 4: return "(prep.)"; + default:return "(error)"; + } + } + + //當清單上的某項被按下時 + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Intent it = new Intent(this, ActWordInfo.class); + it.putExtra("isAddingMode", false); + it.putExtra("SelectedWord", information.get(position+2)); + startActivity(it); + } + + //當【返回】按鈕按下時 + public void btnBack11_Click(View view) {finish();} +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/ActSearchWord.java b/app/src/main/java/com/example/leeyuanair/englishhelper/ActSearchWord.java new file mode 100755 index 0000000..28146e8 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/ActSearchWord.java @@ -0,0 +1,270 @@ +package com.example.leeyuanair.englishhelper; + +import android.app.Activity; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.AssetManager; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.RadioButton; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.access.WordInfo; +import com.example.leeyuanair.englishhelper.act_allwords.ActWordInfo; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; + +public class ActSearchWord extends AppCompatActivity implements RadioButton.OnClickListener, AdapterView.OnItemClickListener { + //Valuables + WordInfo[] words; //所有的單字與其資訊 + String selects; //表示使用者所選的篩選選項。"all"=全部, "n"=名詞, "adj"=形容詞, "v"=動詞, "adv"=副詞, "prep"=介係詞 + ArrayList finds; //所選清單,表示搜尋時所找到的單字清單。 + ArrayAdapter wordlist; //連結ArrayList與清單物件lstFinds之間的物件 + boolean isAddingMode; //判斷是否為Group增加單字的模式 + ArrayList Addition; //紀錄使用者所要增加的單字 + //RadioButton + RadioButton rdoAll, rdoNoun, rdoAdjective, rdoVerb, rdoAdverb, rdoPreposition; + //Button + Button btnSearch; + //TextView + TextView txtSearch; + //ListView + ListView lstFinds; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_search_word); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("單字查詢"); + //初始化變數 + selects = "all"; + finds = new ArrayList<>(); + wordlist = new ArrayAdapter(this,android.R.layout.simple_list_item_1,finds); + //鏈結btnSearch元件 + btnSearch = (Button) findViewById(R.id.btnSearch); + //鏈結txtSearch元件 + txtSearch = (TextView) findViewById(R.id.txtSearch); + //鏈結lstFinds元件,並且與wordlist連結、登錄事件 + lstFinds = (ListView) findViewById(R.id.lstFinds); + lstFinds.setAdapter(wordlist); + lstFinds.setOnItemClickListener(this); + //鏈結所有的RadioButton元件 + rdoAll = (RadioButton) findViewById(R.id.rdoAll); + rdoNoun = (RadioButton) findViewById(R.id.rdoNoun); + rdoAdjective = (RadioButton) findViewById(R.id.rdoAdjective); + rdoVerb = (RadioButton) findViewById(R.id.rdoVerb); + rdoAdverb = (RadioButton) findViewById(R.id.rdoAdverb); + rdoPreposition = (RadioButton) findViewById(R.id.rdoPreposition); + //註冊RadioButton事件 + rdoAll.setOnClickListener(this); + rdoNoun.setOnClickListener(this); + rdoAdjective.setOnClickListener(this); + rdoVerb.setOnClickListener(this); + rdoAdverb.setOnClickListener(this); + rdoPreposition.setOnClickListener(this); + //讀取所有單字 + AssetManager am = getAssets(); + try { + InputStream is = am.open("Words.txt"); + byte[] data = new byte[is.available()]; + is.read(data); is.close(); + words = WordInfo.analyzeWordInfoString(new String(data)); + }catch(Exception ex){ + Toast.makeText(this,"資料讀取錯誤",Toast.LENGTH_SHORT).show(); + } + //判別是否為增加單字模式 + isAddingMode = (boolean) getIntent().getExtras().get("isAddingMode"); + Addition = new ArrayList<>(); + } + + //返回上一層頁面 + public void btnBack2_Click(View view) { + Intent theIntent = new Intent(); + theIntent.putExtra("Addition", Addition); + setResult(0, theIntent); + finish(); + } + + //當【搜尋】按鈕按下時 - 執行查詢單字的功能 + public void btnSearch_Click(View view) { + InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Activity.INPUT_METHOD_SERVICE); //取得輸入介面物件 + inputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0); //隱藏螢幕鍵盤 + String target = txtSearch.getText().toString(); //取得使用者所輸入的文字 + boolean isEnglish = checkEnglish(target.toCharArray()); //判斷使用者輸入的文字是否為英文 + //讀取所有單字資料 + try{ + String[] spis; + finds.clear(); + //依條件尋找單字 + if(isEnglish){ //若使用者輸入的字串為英文時 + //循序尋找有沒有(部分)符合的字串與詞性 + for(WordInfo theWord : words){ + if(theWord.word.contains(target)){ //若使用者所輸入的字與所選單字有部分符合時 + if(checkPartofSpeech(theWord)){ //若該單字有使用者所指定的詞性時 + finds.add(theWord.word); + } + } + } + }else{ //若使用者輸入的字串為非英文時 + //循序尋找是否與使用者所選的詞性相符,且與使用者所輸入的文字有相關的單字 + for(WordInfo theWord : words){ + if(checkPartofMean(theWord, target)){ + finds.add(theWord.word); + } + } + } + //將所找到的資料更新至lstFinds + if(finds.isEmpty())Toast.makeText(this,"未找到任何訊息相符的單字。",Toast.LENGTH_SHORT).show(); + wordlist.notifyDataSetChanged(); + }catch(Exception ex){ + Toast.makeText(this,ex.toString(),Toast.LENGTH_SHORT).show(); + } + } + + //檢測是否為純英文單字字串 + boolean checkEnglish(char[] input){ + boolean isEnglish = true; + for(int i=0;i90) && (input[i]<97 || input[i]>122)) { + isEnglish = false; + break; + } + } + return isEnglish; + } + + //判斷該單字是否有某指定的詞性 + boolean checkPartofSpeech(WordInfo theWord){ + boolean returns = false; + if(selects.equals("all")){ + returns = true; + }else{ + switch (selects){ + case "n" : + returns = theWord.noun!=null; + break; + case "a" : + returns = theWord.adjective!=null; + break; + case "v" : + returns = theWord.verb!=null; + break; + case "adv" : + returns = theWord.adverb!=null; + break; + case "prep" : + returns = theWord.preposition!=null; + break; + default : + } + } + return returns; + } + + //判斷是否與使用者所選的詞性相符,且與使用者所輸入的文字有相關的單字 + boolean checkPartofMean(WordInfo theWord,String target){ + boolean returns = false; + if(selects.equals("all")){ + returns = (theWord.noun!=null) && (theWord.noun.contains(target)) || + (theWord.adjective!=null) && (theWord.adjective.contains(target)) || + (theWord.verb!=null) && (theWord.verb.contains(target)) || + (theWord.adverb!=null) && (theWord.adverb.contains(target)) || + (theWord.preposition!=null) && (theWord.preposition.contains(target)); + }else{ + switch (selects){ + case "n" : + returns = (theWord.noun!=null) && (theWord.noun.contains(target)); + break; + case "a" : + returns = (theWord.adjective!=null) && (theWord.adjective.contains(target)); + break; + case "v" : + returns = (theWord.verb!=null) && (theWord.verb.contains(target)); + break; + case "adv" : + returns = (theWord.adverb!=null) && (theWord.adverb.contains(target)); + break; + case "prep" : + returns = (theWord.preposition!=null) && (theWord.preposition.contains(target)); + break; + default : + } + } + return returns; + } + + //RadioButton事件 - 代表唯一選取的功能 + @Override + public void onClick(View v) { + //判斷呼叫事件的物件類別是否為AppCompatRadioButton,也就是單選按鈕。 + if(v.getClass().getSimpleName().equals("AppCompatRadioButton")){ + uncheckAllRadioButton(); + ((RadioButton) v).setChecked(true); + if(v==rdoAll)selects="all"; + else if(v==rdoNoun)selects="n"; + else if(v==rdoAdjective)selects="a"; + else if(v==rdoVerb)selects="v"; + else if(v==rdoAdverb)selects="adv"; + else if(v==rdoPreposition)selects="prep"; + } + } + + //程序 - 解除所有RadioButton的選取 + void uncheckAllRadioButton(){ + rdoAll.setChecked(false); + rdoNoun.setChecked(false); + rdoAdjective.setChecked(false); + rdoVerb.setChecked(false); + rdoAdverb.setChecked(false); + rdoPreposition.setChecked(false); + } + + //當使用者按下清單裡的某一項時,即顯示使用者選所的單字訊息。 + //若模式為新增群組單字模式時,則傳遞新增單字的布林值true至下個頁面 + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + try{ + Object SelItem = parent.getItemAtPosition(position); + Intent theIntent = new Intent(this, ActWordInfo.class); + theIntent.putExtra("SelectedWord", SelItem.toString()); + theIntent.putExtra("isAddingMode", isAddingMode); + startActivityForResult(theIntent, 0); + }catch(Exception ex){ + Toast.makeText(this,ex.toString(),Toast.LENGTH_SHORT).show(); + } + } + //當下一層的頁面關閉時 + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if(resultCode==0){ + String theWord = data.getExtras().getString("isAdd"); + //若使用者有選擇該單字且該單字之前沒有加入過群組的話則將單字加入 + if(theWord!=null && !Addition.contains(theWord)){ + Addition.add(theWord); + Collections.sort(Addition); + } + } + } + + //攔截使用者所按下的按鍵 - 包含返回、家、視窗等等按鍵 + @Override + public boolean onKeyDown(int keyCode, KeyEvent event){ + if(keyCode == KeyEvent.KEYCODE_BACK){ + Intent theIntent = new Intent(); + theIntent.putExtra("Addition", Addition); + setResult(0, theIntent); + finish(); + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/ActWordPackages.java b/app/src/main/java/com/example/leeyuanair/englishhelper/ActWordPackages.java new file mode 100755 index 0000000..745f570 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/ActWordPackages.java @@ -0,0 +1,44 @@ +package com.example.leeyuanair.englishhelper; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import java.util.Arrays; +import java.util.List; + +public class ActWordPackages extends AppCompatActivity implements ListView.OnItemClickListener { + + //ListView清單元件 + ListView lstAllWordPackages; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_word_packages); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("單字包裹"); + //連結清單元件 + lstAllWordPackages = (ListView) findViewById(R.id.lstAllWordPackages); + lstAllWordPackages.setOnItemClickListener(this); + ArrayAdapter wordPackageAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, MainActivity.WORD_PACKAGES_NAMES); + lstAllWordPackages.setAdapter(wordPackageAdapter); + } + + //當清單元件裡的某項被按下時 + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Intent it = new Intent(this, ActListOfWordPackage.class); + it.putExtra("Index", position); + startActivity(it); + } + + //當【返回】按鈕按下時 + public void btnBack10_Click(View view) { + finish(); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/MainActivity.java b/app/src/main/java/com/example/leeyuanair/englishhelper/MainActivity.java new file mode 100755 index 0000000..ee753b4 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/MainActivity.java @@ -0,0 +1,242 @@ +package com.example.leeyuanair.englishhelper; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.AssetManager; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.access.WordInfo; +import com.example.leeyuanair.englishhelper.act_4selections.Act4Selection; +import com.example.leeyuanair.englishhelper.act_allwords.ActAllVoca; +import com.example.leeyuanair.englishhelper.act_allwords.ActWordInfo; +import com.example.leeyuanair.englishhelper.act_memory.ActMemorySetting; +import com.example.leeyuanair.englishhelper.act_spelling.ActSpellingSetting; + +import java.io.*; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Random; + +public class MainActivity extends AppCompatActivity { + //Global Static Variables 公有靜態變數 + public static LinkedHashMap ALL_WORDS; + public static ArrayList WORDS; + public static LinkedHashMap> GROUPS; + public static ArrayList GROUP_NAMES; + public static int groupCount; + public static LinkedHashMap> WORD_PACKAGES; + public static ArrayList WORD_PACKAGES_NAMES; + //Buttn按鈕元件 + Button btn4Select; + Button btnFillUp; + Button btnMemory; + Button btnSpelling; + Button btnAllVoca; + //TextView文字標籤元件 + TextView lblVersion; + TextView lblWordMessage; + //其他變數 + AssetManager am; + public WordInfo[] words; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("英文幫手"); + //鏈結按鈕物件 + btn4Select = (Button) findViewById(R.id.btn4Select); + btnMemory = (Button) findViewById(R.id.btnMemory); + btnSpelling = (Button) findViewById(R.id.btnSpelling); + btnAllVoca = (Button) findViewById(R.id.btnAllVoca); + //鏈結文字標籤物件 + lblVersion = (TextView) findViewById(R.id.lblVersion); + lblWordMessage = (TextView) findViewById(R.id.lblWordMessage); + //其他設定 + am = getAssets(); + //####讀取單字資料#### + try{ + InputStream is = am.open("Words.txt"); + int length = is.available(); + byte[] data = new byte[length]; + is.read(data); is.close(); + ALL_WORDS = WordInfo.analyzeWordInfo(new String(data)); //將單字資料解析並將其結果放回ALL_WORDS裡 + WORDS = new ArrayList<>(); //建立WORDS英文單字 + WORDS.addAll(ALL_WORDS.keySet()); //將ALL_WORDS的鍵值加入到WORDS裡 + }catch(Exception ex){ + setTitle("Fail"); + lblVersion.setText(ex.toString()); + } + String[] item = new String[5]; + //####是否初次使用此APP的確認函式,環境初始化函式#### + firstInitialize(); + //####讀取單字群組#### + GROUPS = new LinkedHashMap<>(); + GROUP_NAMES = new ArrayList<>(); + try{ + //讀取群組單字檔案 + InputStream is = new FileInputStream(getFilesDir()+"/groups.txt"); + byte[] data = new byte[is.available()]; + is.read(data); is.close(); + String info[] = ((new String(data)).replace("\r","")).split("\n"); //解析字串 + groupCount = Integer.parseInt(info[0]); //群組數量 + for(int i=1;i(Arrays.asList(info[i + 1].split(" ")))); + } + }catch(Exception ex){ + Toast.makeText(MainActivity.this, "群組單字資料讀取錯誤", Toast.LENGTH_SHORT).show(); + } + //####讀取單字包裹檔案#### + WORD_PACKAGES = new LinkedHashMap<>(); //建構WORD_PACKAGES + WORD_PACKAGES_NAMES = new ArrayList<>(); + try{ + InputStream is = am.open("word_packages.txt"); //開起在assets的檔案word_packages.txt + byte[] data = new byte[is.available()]; //建立data變數,並以該資料長度作為陣列的長度 + is.read(data); is.close(); //以byte[]的形式將資料讀出。讀出後將資料流關閉 + //解析字串 + String[] infos = ((new String(data)).replace("\r","")).split("\n"); //以換行符號為單位拆成若干個字串陣列infos[] + String wordPackageName; ArrayList content; //建立wordPackageName與content來暫存包裹名稱及其內容 + String[] spis1, spis2; //spis1與spis2表示infos[]內容的再細分,其中以空白符號作為單位 + //##循序讀取## + for(int i=1;i(); + spis1 = infos[i].split(" "); //解析 + spis2 = infos[i+1].split(" "); //解析 + wordPackageName = spis1[0]; + WORD_PACKAGES_NAMES.add(wordPackageName); + content.add(spis1[1]); content.add(spis1[2]); + content.addAll(Arrays.asList(spis2)); //利用Arrays類別裡的靜態函數asList()來將陣列spis2轉為表準清單 + WORD_PACKAGES.put(wordPackageName, content); //最後加入到WORD_PACKAGES裡 + } + }catch(Exception ex){ + Toast.makeText(MainActivity.this, "單字包裹資料讀取錯誤", Toast.LENGTH_SHORT).show(); + } + //####判別「每日一字」是否需要更新,如果不需要則顯示紀錄的單字;如果需要則更新並顯示其單字 + Calendar c = Calendar.getInstance(); + int y=c.get(c.YEAR), m=c.get(c.MONTH), d=c.get(c.DAY_OF_MONTH); + String dayCheck = (String.valueOf(y)+ ((m+1)>9 ? String.valueOf(m+1) : "0"+String.valueOf(m+1))+ (d>9 ? String.valueOf(d) : "0"+String.valueOf(d))); + try{ + InputStream is = new FileInputStream(getFilesDir()+"/daily.txt"); + byte[] data = new byte[is.available()]; + is.read(data); is.close(); + String[] dailyInfo = ((new String(data)).replace("\r","")).split("\n"); + //確認紀錄日期是否為今日 + if(dailyInfo[0].equals(dayCheck)){ + lblWordMessage.setText(dailyInfo[1]); + }else{ //若不是,則更新日期與單字 + Random rnd = new Random(); rnd.setSeed(rnd.nextInt(100)); + String newWord = WORDS.get(rnd.nextInt(WORDS.size())); + OutputStream os = new FileOutputStream(getFilesDir()+"/daily.txt", false); + os.write((dayCheck+"\r\n"+newWord).getBytes()); + os.flush(); os.close(); + lblWordMessage.setText(newWord); + } + }catch(Exception ex){ + Toast.makeText(MainActivity.this, "每日一字讀取錯誤", Toast.LENGTH_SHORT).show(); + } + } + + //當【字義選擇】按鈕按下時,開啟字義選擇頁面。 + public void btn4Select_Click(View view) { + Intent it = new Intent(this, Act4Selection.class); + startActivity(it); + } + + //當【記憶練習】按鈕按下時,開啟記憶練習設定頁面。 + public void btnMemory_Click(View view) { + Intent it = new Intent(this, ActMemorySetting.class); + startActivity(it); + } + + //當【拼字測驗】按鈕按下時,開啟拼字練習設定頁面 + public void btnSpelling_Click(View view) { + Intent it = new Intent(this, ActSpellingSetting.class); + startActivity(it); + } + + //當【文字包裹】按鈕按下時,開啟文字包裹頁面 + public void btnWordPackage_Click(View view) { + Intent it = new Intent(this, ActWordPackages.class); + startActivity(it); + } + + //當【單字列表】按鈕按下時,開啟單字列表頁面。 + public void btnAllVoca_Click(View view) { + startActivity(new Intent(this, ActAllVoca.class)); + } + + //當lblWordMessage標籤物件按下時 + public void lblWordMessage_Click(View view) { + Intent it = new Intent(this, ActWordInfo.class); + it.putExtra("isAddingMode", false); + it.putExtra("SelectedWord", lblWordMessage.getText().toString()); + startActivity(it); + } + + //環境初始化 - 當使用者為第一次使用此Application時,初始化所有相關的變數。 + protected void firstInitialize(){ + try{ + //確認群組檔案是否存在,如果不存在就新增一個新的群組檔案 + File groups = new File(getFilesDir()+"/groups.txt"); + if(!groups.exists()){ + groups.createNewFile(); + OutputStream os = new FileOutputStream(getFilesDir()+"/groups.txt"); + os.write(("0").getBytes()); + os.flush(); os.close(); + }else{ + //groups.delete(); + //Toast.makeText(this,"Deleted",Toast.LENGTH_SHORT).show(); + } + //確認每日紀錄的檔案是否存在,如果不存在則新創一個 + File daily = new File(getFilesDir()+"/daily.txt"); + if(!daily.exists()){ + daily.createNewFile(); + OutputStream os = new FileOutputStream(getFilesDir()+"/daily.txt"); + String word = WORDS.get((new Random()).nextInt(WORDS.size())); //隨機選取一個單字 + Calendar c = Calendar.getInstance(); //取得當前時間 + int y=c.get(c.YEAR), m=c.get(c.MONTH), d=c.get(c.DAY_OF_MONTH); + os.write((String.valueOf(y) + + ((m + 1) > 9 ? String.valueOf(m + 1) : "0" + String.valueOf(m + 1)) + + (d > 9 ? String.valueOf(d) : "0" + String.valueOf(d)) + + "\r\n" + word).getBytes()); + os.flush(); os.close(); + } + }catch(Exception ex){ + lblVersion.setText(ex.toString()); + } + } + + //當版本訊息lblVersion按下時 + public void lblVersion_Click(View view) { + AlertDialog.Builder msgBox = new AlertDialog.Builder(this) + .setTitle("關於英文幫手") + .setMessage("此應用程式由Nebula3122製作。\r\n若有錯誤的地方就麻煩通知我吧,\r\n我會進行修正的動作,謝謝!") + .setPositiveButton("OK", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}) + .setNeutralButton("Email", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); + emailIntent.setType("plain/text"); + emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"alan159753@gmail.com"}); + emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "英文幫手 - 回應"); + emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "內文"); + startActivity(Intent.createChooser(emailIntent, "Email回覆")); + } + }); + msgBox.show(); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/access/FTPThread.java b/app/src/main/java/com/example/leeyuanair/englishhelper/access/FTPThread.java new file mode 100755 index 0000000..ab27200 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/access/FTPThread.java @@ -0,0 +1,25 @@ +package com.example.leeyuanair.englishhelper.access; + +import android.content.Context; +import android.widget.Toast; + +import org.apache.commons.net.ftp.FTPClient; + +/** + * Created by Lee Yuan Air on 2016/2/22. + */ +public class FTPThread extends Thread { + FTPClient ftp; + public void setFtp(FTPClient ftp){ + this.ftp = ftp; + } + @Override + public void run(){ + try{ + ftp.connect("192.168.1.216",21); + }catch(Exception ex){ + + } + + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/access/TheManager.java b/app/src/main/java/com/example/leeyuanair/englishhelper/access/TheManager.java new file mode 100755 index 0000000..b13e1ee --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/access/TheManager.java @@ -0,0 +1,29 @@ +package com.example.leeyuanair.englishhelper.access; + +import android.app.Application; +import android.util.Log; + +import com.example.leeyuanair.englishhelper.access.WordInfo; + +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * Created by Lee Yuan Air on 2016/4/10. + * + */ +public class TheManager extends Application{ + + public WordInfo[] all_word; + + public TheManager(){ + super(); + + } + + public void start(){ + + } +} + + diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/access/WordInfo.java b/app/src/main/java/com/example/leeyuanair/englishhelper/access/WordInfo.java new file mode 100755 index 0000000..3c1e374 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/access/WordInfo.java @@ -0,0 +1,108 @@ +package com.example.leeyuanair.englishhelper.access; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; + +/** + * Created by Lee Yuan Air on 2016/2/21. + * + */ +public class WordInfo { + public String word; + public String noun, adjective, verb, adverb, preposition; + public WordInfo(String word, String noun, String adjective, String verb, String adverb, String preposition){ + this.word = word; + this.noun = noun; + this.adjective = adjective; + this.verb = verb; + this.adverb = adverb; + this.preposition = preposition; + } + public void setWord(String word){this.word = word;} + public void setNoun(String noun){this.noun = noun;} + public void setAdjective(String adjective){this.adjective = adjective;} + public void setVerb(String verb){this.verb = verb;} + public void getAdverb(String adverb){this.adverb = adverb;} + public void setPreposition(String preposition){this.preposition = preposition;}; + public static void sort(WordInfo[] data){ + WordInfo temp; + for(int i=1;i=i;q--){ + if(data[q-1].word.compareTo(data[q].word)>0){ + temp = data[q-1]; + data[q-1] = data[q]; + data[q] = temp; + } + } + } + } + + //解析字串並轉入HashMap集合物件裡的資料,最後回傳之。 + public static LinkedHashMap analyzeWordInfo(String inputs){ + String[] info = (inputs.replace("\r","")).split("\n"); + LinkedHashMap wordinfos = new LinkedHashMap<>(); + String[] spis; + String word,n,a,v,adv,prep; + for(int i=1;i 0) ? num : 1)); + } + + //當按鈕物件btnChangeGroup1_Click按下時 + public void btnChangeGroup1_Click(View view) { + final ArrayAdapter grouplist = new ArrayAdapter(this, android.R.layout.simple_list_item_1); + byte[] data; + grouplist.add("所有單字"); + //讀取群組檔案 + try{ + InputStream is = new FileInputStream(getFilesDir()+"/groups.txt"); + data = new byte[is.available()]; + is.read(data); is.close(); + final String[] info = ((new String(data)).replace("\r","")).split("\n"); + for(int i=1;i=0){ + //確認該選擇的群組內容不為空 + if(!info[Selection*2+2].equals("0")){ + int n=0, a=0, v=0, adv=0, prep=0; //紀錄個詞性在群組內的數量 + String[] spis = info[Selection*2+2].split(" "); //分解群組內容(字串) + //若群組單字量大於4時,符合最低群組取用條件 + if(spis.length>4){ + //標示該群組可進行測驗 + qualified = true; + //逐一地解析內容,並篩選、紀錄詞性總數 + for(int i=0;i3; A = a>3; V = v>3; ADV = adv>3; PREP = prep>3; + extraMsg = ((N && A && V && ADV && PREP) ? "" : "由於此群組內的") + + (N ? "" : " 名詞") + (A ? "" : " 形容詞") + (V ? "" : " 動詞") + (ADV ? "" : " 副詞") + (PREP ? "" : " 介係詞") + + ((N && A && V && ADV && PREP) ? "" : "類的數量小於3個,因此系統若隨機選到該類詞性時,其選項會包括群組外的同詞性單字。"); + //若【選項中僅出現群組裡的單字】的格子勾選時,顯示其訊息 + lblExtraMsg1.setTextColor(Color.argb(255,160,160,160)); + if(chkOnlyGroupItem1.isChecked()){ + lblExtraMsg1.setText(extraMsg); + } + }else{ //若群組單字量小於等於4時,則告知使用者該群組不符合最低條件。 + //標示該群組不能進行測驗 + qualified = false; + lblExtraMsg1.setTextColor(Color.RED); + extraMsg = "群組內的單字量必須大於4個才能開始測驗!"; + lblExtraMsg1.setText(extraMsg); + } + }else{ //若該群組為空時,也就是單字量為0時,告知使用者該群組不可用 + //標示該群組不能進行測驗 + qualified = false; + lblExtraMsg1.setTextColor(Color.RED); + extraMsg = "由於所選群組內無任何單字,因此無法開始測驗!"; + lblExtraMsg1.setText(extraMsg); + } + }else{ //當使用者選擇「所有單字」選項時 + //標示該群組可進行測驗 + qualified = true; + lblExtraMsg1.setTextColor(Color.argb(255,160,160,160)); + lblExtraMsg1.setText(""); + extraMsg = ""; + } + } + }); + //顯示對話方塊 + alert.show(); + }catch(Exception ex){ + Toast.makeText(Act4Selection.this, "群組檔案讀取錯誤。", Toast.LENGTH_SHORT).show(); + } + + } + + //當【選項中僅出現群組裡的單字】勾選方塊按下時 + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(qualified){ + if(isChecked) { + lblExtraMsg1.setText(extraMsg); + } else { + lblExtraMsg1.setText(""); + } + } + } + + //當【返回】按鈕按下時 + public void btnBack_Click(View view) {finish();} + + //當【說明】按鈕按下時 + public void btnExplanation1_Click(View view) { + final AlertDialog.Builder adExp1, adExp2, adExp3; + //設定對話方塊的內容 + adExp3 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("在設定的部分,你可以選擇目前所定義的群組單字、設定題目數及設定每一題的回答時間。" + + "完成之後你就可以按下【開始測驗】來進行測驗了!") + .setPositiveButton("完成", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + adExp2 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("若你選擇正確,增加一次回答正確的紀錄;若選擇錯誤,則會公布正確答案並增加一次回答錯誤的紀錄。") + .setPositiveButton("下一頁", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + adExp3.show(); + } + }); + adExp1 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("此測驗方法與四選一選擇題一樣,題目會秀出英文單字與其詞性," + + "而下方有四個寫著不同中文意義的按鈕,你只需要選出與題目相符的答案。") + .setPositiveButton("下一步", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + adExp2.show(); + } + }); + adExp1.show(); + } + + //當【開始測驗】按鈕按下時 + public void btnStartTest1_Click(View view) { + //如果所選群組符合條件 + if(qualified){ + Intent it = new Intent(Act4Selection.this,ActMultipleChoice.class); + it.putExtra("Selection", Selection); //使用者所選的群組 + it.putExtra("Amount", Integer.valueOf(txtQAmount1.getText().toString())); //測驗的題目總數 + it.putExtra("SecPerQ", skbTimeSet1.getProgress()); //一題的限制秒數 + //選項的單字是否僅出現群組中所有的單字 + if(chkOnlyGroupItem1.isChecked()){ + it.putExtra("cN", N); it.putExtra("cA", A); it.putExtra("cV", V); + it.putExtra("cADV", ADV); it.putExtra("cPREP", PREP); + }else{ + it.putExtra("cN", false); it.putExtra("cA", false); it.putExtra("cV", false); + it.putExtra("cADV", false); it.putExtra("cPREP", false); + } + startActivity(it); + } + } + + ////SeekBar滑桿物件的事件處理副程式 + //當滑感滑動時 + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if(progress==0){ + lblTimePerQ1.setText("每題答題時間: 無限制"); + }else{ + lblTimePerQ1.setText("每題答題時間: "+progress+"秒"); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} + + ////####################### + + +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/Act4SelectionResult.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/Act4SelectionResult.java new file mode 100755 index 0000000..0b4e6e0 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/Act4SelectionResult.java @@ -0,0 +1,95 @@ +package com.example.leeyuanair.englishhelper.act_4selections; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; + +public class Act4SelectionResult extends AppCompatActivity implements ListView.OnItemClickListener { + //Global Variables + ArrayList QuestionList; + ArrayList AnswerList; + ArrayList UserAnswerList; + //TextView文字標籤物件 + TextView lblQuestionAmount1; + TextView lblRights1; + TextView lblWrongs1; + //ListView清單物件 + ListView lstAnswerLog1; + //ArrayAdapter清單陣列連結物件 + ArrayAdapter answerLogAdapter; + //AlertDialog.Builder對話方塊建立物件 + AlertDialog.Builder aswInfo; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act4_selection_result); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("字義選擇 - 測驗結果"); + //連結文字標籤物件 + lblQuestionAmount1 = (TextView) findViewById(R.id.lblQuestionAmount1); + lblRights1 = (TextView) findViewById(R.id.lblRights1); + lblWrongs1 = (TextView) findViewById(R.id.lblWrongs1); + //連結清單物件 + lstAnswerLog1 = (ListView) findViewById(R.id.lstAnswerLog1); + //取得測驗後的資料 + Bundle msg = getIntent().getExtras(); + QuestionList = (ArrayList) msg.get("QuestionList"); + AnswerList = (ArrayList) msg.get("AnswerList"); + UserAnswerList = (ArrayList) msg.get("UserAnswerList"); + lblQuestionAmount1.setText(String.valueOf(msg.getInt("maxQ"))); + lblRights1.setText(String.valueOf(msg.getInt("rights"))); + lblWrongs1.setText(String.valueOf(msg.getInt("maxQ")-msg.getInt("rights"))); + //設定ArrayAdapter,並將其連結至lstAnswerLog1裡 + answerLogAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1); + String[] itemSlot; + for(int i=0; i parent, View view, int position, long id) { + try { + if (AnswerList.get(position).equals(UserAnswerList.get(position))) { + aswInfo.setTitle("此題答對"); + aswInfo.setMessage("答案: " + QuestionList.get(position)[AnswerList.get(position)]); + } else { + aswInfo.setTitle("此題答錯"); + aswInfo.setMessage("正確答案: " + QuestionList.get(position)[AnswerList.get(position)] + "\r\n你的答案: " + + ((UserAnswerList.get(position).equals(-1)) ? "*超出時間" : QuestionList.get(position)[UserAnswerList.get(position)])); + } + aswInfo.show(); + }catch(Exception ex){ + Toast.makeText(Act4SelectionResult.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + void keep(){ + + } + + //當【返回至設定頁面】按鈕按下時 + public void btnBack5_Click(View view) { + finish(); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/ActMultipleChoice.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/ActMultipleChoice.java new file mode 100755 index 0000000..474a8c6 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_4selections/ActMultipleChoice.java @@ -0,0 +1,356 @@ +package com.example.leeyuanair.englishhelper.act_4selections; + +import android.app.AlertDialog; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; + +public class ActMultipleChoice extends AppCompatActivity { + //Global Variable + int maxQ, Q; //總題數, 目前答題 + int timelimit, timecount; //時間倒數值, 計時值 + int rights; //答對題數 + boolean cN, cA, cV, cADV, cPREP; //該詞性是否只取用群組中的單字 + boolean checks[]; + public int delay; //延遲時間 + public int mode; //表示目前計數的模式 + int backUpTimeCount; //計算使用者按下返回鍵時再按下一次返回鍵間的間隔時間 + //若在該時間之內則讓使用者退出測驗 + //題目方面的變數 + ArrayList QuestionList; //題目清單 + ArrayList AnswerList; //答案清單 + ArrayList UserAnswerList; //紀錄使用者的回答 + //Timer計時器 + Timer countdownTimer; + //TextView文字標籤物件 + TextView lbl4SelStatus1, lbl4SelStatus2; + TextView lbl4SelQuestion; + //Button按鈕物件 + Button btnSelection1, btnSelection2, btnSelection3, btnSelection4; + //ProgressBar進度顯示物件 + ProgressBar pgbCountdown1; + //AlertDialog.Builder對話框建立物件 + AlertDialog AnswerShows; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_multiple_choice); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("字義選擇"); + Bundle msg = getIntent().getExtras(); + mode = 1; delay=4; + //##連結文字標籤物件 + lbl4SelStatus1 = (TextView) findViewById(R.id.lbl4SelStatus1); + lbl4SelStatus2 = (TextView) findViewById(R.id.lbl4SelStatus2); + lbl4SelQuestion = (TextView) findViewById(R.id.lbl4SelQuestion); + //##連結按鈕物件 + btnSelection1 = (Button) findViewById(R.id.btnSelection1); + btnSelection2 = (Button) findViewById(R.id.btnSelection2); + btnSelection3 = (Button) findViewById(R.id.btnSelection3); + btnSelection4 = (Button) findViewById(R.id.btnSelection4); + //##連結進度表示物件 並 為其建立獨立的執行續以連結倒數的動作 + pgbCountdown1 = (ProgressBar) findViewById(R.id.pgbCountdown1); + //##初始化對話框物件 + AnswerShows = (new AlertDialog.Builder(this)).create(); + AnswerShows.setTitle("答案"); + AnswerShows.setCancelable(false); + //##取得資料 + maxQ = msg.getInt("Amount"); + timelimit = msg.getInt("SecPerQ") * 1000; + checks = new boolean[5]; + checks[0] = msg.getBoolean("cN"); checks[1] = msg.getBoolean("cA"); checks[2] = msg.getBoolean("cV"); + checks[3] = msg.getBoolean("cADV"); checks[4] = msg.getBoolean("cPREP"); + //##初始化變數 + timecount = 0; Q = 0; + rights = 0; + countdownTimer = new Timer(); + countdownTimer.schedule(countdownTask, 0, 1); + //將進度顯示物件的最大直設為timelimit + pgbCountdown1.setMax(1000); + //##初始化介面 + lbl4SelStatus1.setText("總題數: "+maxQ+" ,目前答題: 0"); + //##初始化題目列表 + InitQuestionList(msg.getInt("Selection")); + } + + //TimerTask計時器工作物件 - 當Timer倒數計時至一定時間時所執行的動作,其中利用此物件作為Timer工作表。 + public final TimerTask countdownTask = new TimerTask() { + @Override + public void run() { + //####透過runOnUiThread來取得合法控制使用者介面物件的權利#### + runOnUiThread(new Runnable() { + @Override + public void run() { + //若backUpTimeCount大於0,則將其減1 + if (backUpTimeCount > 0) backUpTimeCount--; + //####以下為測驗判斷程序#### + //依照mode是否為真,將timecount+1或-1 + timecount += mode; + //如果延遲時間計數delay大於0 - 為使用者剛進入時的緩衝時間 + if (delay > 0) { + //每次做1秒的倒數,當倒數至1秒時,delay-1,時間計數timecount重設回0,此動作直到delay==0為止。 + if (timecount == 1000) { + delay--; + timecount = 0; + //當delay計數完時,將進度顯示物件的最大值設為使用者所限制的時間timelimit + if (delay == 0) { + pgbCountdown1.setMax((timelimit>0) ? timelimit : 500); + if (timelimit == 0) { + mode = 0; + timecount=1; + } + lbl4SelQuestion.setText(QuestionList.get(Q)[0]); + btnSelection1.setText(QuestionList.get(Q)[1]); + btnSelection2.setText(QuestionList.get(Q)[2]); + btnSelection3.setText(QuestionList.get(Q)[3]); + btnSelection4.setText(QuestionList.get(Q)[4]); + } else { + //若delay沒有計數完,則顯示倒數數值delay + lbl4SelQuestion.setText(String.valueOf(delay)); + } + } + } else { //如果delay==0時(即delay<0時),也就是使用者已經進入測驗狀態 + if (mode == 1) { + //判別計數時間是否到達限制時間 + if (timecount > timelimit) { + //如果以到達時間的話,將mode(測驗模式)設為false,表示目前暫停測驗 + //並告知使用者的作答時間已經超過預設時間、顯示答案及更新答題狀態 + //最後設定2秒短暫延遲時間讓使用者可以看得到答案 + mode = -1; + UserAnswerList.add(-1); + AnswerShows.setTitle("超過時間!"); + AnswerShows.setMessage("答案: " + QuestionList.get(Q)[AnswerList.get(Q)]); + AnswerShows.show(); + pgbCountdown1.setProgress(2000); + pgbCountdown1.setMax(2000); + timecount = 2000; + } + } else { + //若顯示答案的時間完畢後 + if (timecount == 0) { + //確認全部題目是否答完 + if (Q == maxQ - 1) { + AnswerShows.dismiss(); //把AnswerShows對話方塊取消掉 + countdownTimer.cancel(); + countdownTimer.purge(); + //開啟結果顯示頁面 + Intent it = new Intent(ActMultipleChoice.this, Act4SelectionResult.class); + it.putExtra("QuestionList", QuestionList); + it.putExtra("AnswerList", AnswerList); + it.putExtra("UserAnswerList", UserAnswerList); + it.putExtra("maxQ", maxQ); + it.putExtra("rights", rights); + startActivityForResult(it, 0); + } else { //如果題目尚未全部答完的話,則目前題號+1,並更新題目內容 + mode = (timelimit == 0) ? 0 : 1; //把mode轉為true,為答題模式 + timecount = (timelimit == 0) ? 1 : 0; //若時限為無限制,則把timecount設為1,以免誤判 + AnswerShows.dismiss(); //把AnswerShows對話方塊取消掉 + //更新題目內容 + Q++; //題號+1 + //依照目前的題號,從題目清單裡提出題目與四個選項,並放入所設定的位置 + lbl4SelQuestion.setText(QuestionList.get(Q)[0]); + btnSelection1.setText(QuestionList.get(Q)[1]); + btnSelection2.setText(QuestionList.get(Q)[2]); + btnSelection3.setText(QuestionList.get(Q)[3]); + btnSelection4.setText(QuestionList.get(Q)[4]); + //更新答題數狀態 + lbl4SelStatus1.setText("總題數: " + maxQ + ", 目前答題: " + (Q + 1)); + lbl4SelStatus2.setText("答對題數: " + String.valueOf(rights) + " ,答錯題數: " + String.valueOf(Q - rights)); + pgbCountdown1.setMax((timelimit>0) ? timelimit : 500); //將進度顯示物件的最大值設為timelimit + } + } + } + } + //更新進度顯示物件的進度數值 + pgbCountdown1.setProgress(timecount); + } + }); + //############################################################ + } + }; + + //程序 - 初始化題目列表 + void InitQuestionList(int index){ + ArrayList tarGroup = (index>=0) ? (MainActivity.GROUPS.get(MainActivity.GROUP_NAMES.get(index))) : (MainActivity.WORDS); //取得使用者所選的群組 + Random rnd = new Random(); //亂數產生器 + rnd.setSeed(rnd.nextInt(100)); + QuestionList = new ArrayList<>(); //題目清單 + AnswerList = new ArrayList<>(); //答案清單回答紀錄(清單) + UserAnswerList = new ArrayList<>(); //使用者 + int type, ans; //type表示目前所視單字的某項詞性: 0為名詞、1為形容詞、2為動詞、3為副詞、4為介係詞; ans表示答案正確項 + //判別使用者所選定的題數數量是否大於群組內所有單字的數量 + ArrayList rndGroup = new ArrayList<>(); //初始化基本亂數題庫 + //如果使用者所指定的題目數量超過所選單字群組內的單字數量的話,則亂數取得動作就做1次以上 + //其次數依照maxQ使用者指定出題數 除以 所選群組內單字量後結果的+1次 + for(int i=1;i<=(maxQ/tarGroup.size()+1);i++){ + rndGroup.addAll(randomizeItems(tarGroup)); + } + String[] itemPorts; //項目插槽 - 0為詞性, 1~4為答案選項 + //##依次對每一個項目做整理的動作 + for(int i=1;i<=maxQ;i++){ + //##更新項目插槽 + itemPorts = new String[5]; + //##取得單字資訊 + String[] wordinfo = MainActivity.ALL_WORDS.get(rndGroup.get(i)); + type = rnd.nextInt(5); //隨機取得此字中的某一詞性 + while(wordinfo[type]==null){ //判斷所選單字有沒有該詞性,如果無,則項次+1直到有為止 + type++; + if(type==5) type=0; + } + ans = rnd.nextInt(4)+1; //從1~4中隨機選取一項(號)作為要放入答案的地方 + AnswerList.add(ans); //將亂數所取的答案號放入答案清單中 + itemPorts[ans] = wordinfo[type]; //將正確的中文詞性意思放入該項中 + switch(type) { //依照所紀錄數值來決定要放入何種詞性(字串) + case 0: + itemPorts[0] = rndGroup.get(i) + " (n.)"; + break; + case 1: + itemPorts[0] = rndGroup.get(i) + " (adj.)"; + break; + case 2: + itemPorts[0] = rndGroup.get(i) + " (v.)"; + break; + case 3: + itemPorts[0] = rndGroup.get(i) + " (adv.)"; + break; + case 4: + itemPorts[0] = rndGroup.get(i) + " (prep.)"; + break; + default: + break; + } + //##由項目插槽的標號1做到標號4 + //設定初始亂數位置,當選擇到某一數值後,其後都會逐次往下,如: rndNum亂數取得到11,之後所要選的亂數都會是12,13,14...逐次下去的 + int rndNum = checks[type] ? (tarGroup.size()) : (MainActivity.ALL_WORDS.size()); + rndNum = rnd.nextInt(rndNum); + String selected; //表示由亂數所選到的英文單字 + String[] selectedWordInfo; //表示所選到的英文單字的詞性內容 + for(int q=1 ; q<=4 ; q++) { + /* + //此部分可以簡化// + */ + //如果標號q內的內容為無值的話 + if(itemPorts[q]==null){ + //確認是否要在單字群組裡隨機選取 + if (checks[type]) { + //##以rndNum選擇一個單字,直到符合為止 + do{ + if(rndNum < tarGroup.size()-1) + rndNum++; + else + rndNum=0; + //單字群組中從取得該單字 + selected = tarGroup.get(rndNum); + //取得該單字的訊息 + selectedWordInfo = MainActivity.ALL_WORDS.get(selected); + //最後確認所選的單字有沒有該詞性 *並且 確認所選單字並不與目標單字相符 + }while(selectedWordInfo[type]==null || selectedWordInfo[type].equals(itemPorts[ans])); + itemPorts[q] = selectedWordInfo[type]; //將亂數所選到的英文單字的指定詞性的內容放入位於 q 號的項目插槽裡 + } else { //從所有單字裡隨機選取 + //##以rndNum選擇一個單字,直到符合為止 + do{ + rndNum++; + if(rndNum >= MainActivity.ALL_WORDS.size()) + rndNum=0; + //單字群組中從取得該單字 + selected = MainActivity.WORDS.get(rndNum); + //取得該單字的訊息 + selectedWordInfo = MainActivity.ALL_WORDS.get(selected); + //最後確認所選的單字有沒有該詞性 *並且 確認所選單字並不與目標單字相符 + }while(selectedWordInfo[type]==null || selectedWordInfo[type].equals(itemPorts[ans])); + itemPorts[q] = selectedWordInfo[type]; //將亂數所選到的英文單字的指定詞性的內容放入位於 q 號的項目插槽裡 + } + } + } + //將處理好的項目插槽(題目及選項)放入問題清單中 + QuestionList.add(itemPorts); + } + } + //InitQuestionList -> 函式 - 回傳內容不重覆的隨機單字清單 + ArrayList randomizeItems(ArrayList group){ + ArrayList rndGroup = (ArrayList) group.clone(); //複製群組單字至rndGroup裡 + //建立亂數產生器物件 + Random rnd = new Random(); + rnd.setSeed(rnd.nextInt(100)); + //num表示由亂數所取得的整數數值; temp表示兩變數間交換內容時的暫存處 + int num; String temp; + //##開始隨機排列內容: + //作用範圍一次一次地從最大住標處做到至住標1 + //將所取的亂數放入num後,依num從rndGroup裡取出該英文單字後放入temp裡 + //然後再將rndGroup裡住標num處的英文單字覆蓋為目前範圍的最後一個英文單字(也就是在住標 i 處的英文單字) + //最後將temp覆蓋至rndGroup裡的住標 i 處,就可完成兩變數內容交換的動作了。 + //##以上為不重複隨機排列集合內容的方法 + for(int i = rndGroup.size()-1;i>0;i--) { + num = rnd.nextInt(i + 1); + temp = rndGroup.get(num); + rndGroup.set(num, rndGroup.get(i)); + rndGroup.set(i, temp); + } + return rndGroup; + } + + //當btnSelection1按鈕物件按下後 + public void btnSelection1_Click(View view) {if(delay==0){answerResult(AnswerList.get(Q)==1); UserAnswerList.add(1);}} + //當btnSelection2按鈕物件按下後 + public void btnSelection2_Click(View view) {if(delay==0){answerResult(AnswerList.get(Q)==2); UserAnswerList.add(2);}} + //當btnSelection3按鈕物件按下後 + public void btnSelection3_Click(View view) {if(delay==0){answerResult(AnswerList.get(Q)==3); UserAnswerList.add(3);}} + //當btnSelection4按鈕物件按下後 + public void btnSelection4_Click(View view) {if(delay==0){answerResult(AnswerList.get(Q)==4); UserAnswerList.add(4);}} + + //程序 - 使用者答錯或答對時的系統反應 + void answerResult(boolean isRight){ + rights += isRight ? 1 : 0; + AnswerShows.setTitle(isRight ? "答對!" : "答錯!"); + AnswerShows.setMessage("答案: " + QuestionList.get(Q)[AnswerList.get(Q)]); + AnswerShows.show(); + mode = -1; + pgbCountdown1.setProgress(2000); + pgbCountdown1.setMax(2000); + timecount = 2000; + } + + //當下層的頁面關閉時,也就是結果顯示頁面關閉時,回到此頁面後直接關閉 + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + finish(); + } + + //攔截使用者所按下的按鍵 - 包含返回、家、視窗等等按鍵 + @Override + public boolean onKeyDown(int keyCode, KeyEvent event){ + if(keyCode == KeyEvent.KEYCODE_BACK){ + if(backUpTimeCount==0){ + backUpTimeCount=2000; + Toast.makeText(ActMultipleChoice.this, "再按一次即可離開測驗", Toast.LENGTH_SHORT).show(); + }else{ + finish(); + } + return true; + } + return super.onKeyDown(keyCode, event); + } + + //當此頁面要關閉的時候 + @Override + public void onDestroy(){ + countdownTimer.cancel(); + countdownTimer.purge(); + super.onDestroy(); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAddingGroup.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAddingGroup.java new file mode 100755 index 0000000..8ae4012 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAddingGroup.java @@ -0,0 +1,49 @@ +package com.example.leeyuanair.englishhelper.act_allwords; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.EditText; + +import com.example.leeyuanair.englishhelper.R; + +public class ActAddingGroup extends AppCompatActivity { + //EditText + EditText txtNewGroupName; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_adding_group); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("建立新的群組"); + //鏈結文字輸入方塊物件 + txtNewGroupName = (EditText) findViewById(R.id.txtNewGroupName); + } + + public void btnCancelNewGroup_Click(View view) { + Intent resent = new Intent(); + resent.putExtra("NewGroupName", "$NONE"); + setResult(0, resent); + finish(); + } + + public void btnAddNewGroupName_Click(View view) { + String groupName = txtNewGroupName.getText().toString(); + if(groupName.length()==0 || groupName.equals("$NONE")){ + AlertDialog.Builder ad = new AlertDialog.Builder(this); + ad.setTitle("無效的群組名稱"); + ad.setMessage("群組名稱不可為空白或\"$NONE\"\n請重新輸入"); + ad.setPositiveButton("OK", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + ad.show(); + }else{ + Intent resent = new Intent(); + resent.putExtra("NewGroupName", txtNewGroupName.getText().toString()); + setResult(0, resent); + finish(); + } + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAllVoca.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAllVoca.java new file mode 100755 index 0000000..5cba855 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActAllVoca.java @@ -0,0 +1,55 @@ +package com.example.leeyuanair.englishhelper.act_allwords; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.ListView; + +import com.example.leeyuanair.englishhelper.ActSearchWord; +import com.example.leeyuanair.englishhelper.R; + +public class ActAllVoca extends AppCompatActivity implements AdapterView.OnItemClickListener { + //Buttons + Button btnBackUp; + //ListView + ListView lstWords; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_all_voca); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("單字列表"); + //從Intent中解析Bundle + Bundle msg = getIntent().getExtras(); + //連結按鈕物件 + btnBackUp = (Button) findViewById(R.id.btnBackUp); + //鏈結清單物件 + lstWords = (ListView) findViewById(R.id.lstWords); + lstWords.setOnItemClickListener(this); + } + //返回上一層 + public void btnBackUp_Click(View view) {finish();} + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Object SelItem = parent.getItemAtPosition(position); + Intent theIntent = new Intent(this,ActPieceVoca.class); + theIntent.putExtra("SelectedItem",SelItem.toString()); + startActivity(theIntent); + } + + public void btnFinder_Click(View view) { + Intent theIntent = new Intent(this, ActSearchWord.class); + theIntent.putExtra("isAddingMode", false); + startActivity(theIntent); + } + + public void btnGrouping_Click(View view) { + Intent theIntent = new Intent(this,ActGrouping.class); + startActivity(theIntent); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActEditingGroup.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActEditingGroup.java new file mode 100755 index 0000000..f791789 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActEditingGroup.java @@ -0,0 +1,124 @@ +package com.example.leeyuanair.englishhelper.act_allwords; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.ActSearchWord; +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; +import java.util.Collections; + +public class ActEditingGroup extends AppCompatActivity implements ListView.OnItemClickListener { + //Valuable + String groupName; //群組名稱 + ArrayList groupArray; //指定群組中的所有單字 + ArrayAdapter arrayAdapter; + ArrayList Selections; + //ListView清單物件 + ListView lstGroupWords; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_editing_group); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + //鏈結清單物件 + lstGroupWords = (ListView) findViewById(R.id.lstGroupWords); + lstGroupWords.setOnItemClickListener(this); + //初始化變數// + Selections = new ArrayList<>(); + //讀取上一層所給的資料 + groupName = getIntent().getExtras().getString("groupName"); + setTitle("群組\"" + groupName + "\"內的所有單字"); + groupArray = MainActivity.GROUPS.get(groupName); + if(groupArray.get(0).equals("0")) + groupArray.remove(0); + arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_multiple_choice, groupArray); + //將arrayAdapter鏈結至lstGroupWords + lstGroupWords.setAdapter(arrayAdapter); + } + + //當【返回】按鈕按下時 + public void btnBack4_Click(View view) { + Intent newIntent = new Intent(); + if(groupArray.size()==0) + groupArray.add("0"); + setResult(1, newIntent); + finish(); + } + + //當【新增單字】按鈕按下時 + public void btnAddWord_Click(View view) { + Intent theIntent = new Intent(this, ActSearchWord.class); + theIntent.putExtra("isAddingMode", true); + startActivityForResult(theIntent, 0); + } + //當【刪除單字】按鈕按下時 + public void btnRemoveWord_Click(View view) { + if(!Selections.isEmpty()) { + try { + Collections.sort(Selections); + for (int i = 0; i < arrayAdapter.getCount(); i++) + lstGroupWords.setItemChecked(i, false); + for (int i = Selections.size() - 1; i >= 0; i--) + groupArray.remove((int) Selections.get(i)); + Selections.clear(); + arrayAdapter.notifyDataSetChanged(); + } catch (Exception ex) { + Toast.makeText(ActEditingGroup.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + }else{ + Toast.makeText(ActEditingGroup.this, "請選擇欲刪除的單字", Toast.LENGTH_SHORT).show(); + } + } + + //當下一層頁面關閉後 + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if(resultCode==0){ + ArrayList Addition = (ArrayList) data.getExtras().get("Addition"); + for(String item : Addition){ + if(!groupArray.contains(item)){ + groupArray.add(item); + } + } + Collections.sort(groupArray); + arrayAdapter.notifyDataSetChanged(); + } + } + + //當使用者按下清單裡某一項時 + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + try{ + if(Selections.contains(position)) + Selections.remove(Selections.indexOf(position)); + else + Selections.add(position); + }catch (Exception ex){ + Toast.makeText(ActEditingGroup.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //攔截使用者所按下的按鍵 - 包含返回、家、視窗等等按鍵 + @Override + public boolean onKeyDown(int keyCode, KeyEvent event){ + if(keyCode == KeyEvent.KEYCODE_BACK){ + Intent newIntent = new Intent(); + if(groupArray.size()==0) + groupArray.add("0"); + setResult(1, newIntent); + finish(); + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActGrouping.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActGrouping.java new file mode 100755 index 0000000..bfbe32f --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActGrouping.java @@ -0,0 +1,170 @@ +package com.example.leeyuanair.englishhelper.act_allwords; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Set; + +public class ActGrouping extends AppCompatActivity { + //變數 + HashMap> groups; + //ArrayList groups; //紀錄所有Groups的名稱 + ArrayAdapter arrayAdapter; + int grpCount; + int SelPosition; + //ListView + ListView lstGroups; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_grouping); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("單字群組"); + //初始化變數 + groups = new HashMap<>(); + arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_single_choice, MainActivity.GROUP_NAMES); + SelPosition = -1; + //鏈結清單元件 + lstGroups = (ListView) findViewById(R.id.lstGroups); + lstGroups.setAdapter(arrayAdapter); + lstGroups.setChoiceMode(ListView.CHOICE_MODE_SINGLE); + } + + //當【返回】按鈕按下 - 返回上一層 + public void btnBack3_Click(View view) { + try { + OutputStream os = new FileOutputStream(getFilesDir() + "/groups.txt", false); //false -> 複寫檔案 + String saves = String.valueOf(MainActivity.groupCount); + //束整資料 - 將資料轉換成字串的形式並儲存 + for(String key : MainActivity.GROUP_NAMES){ + saves += "\r\n" + key + "\r\n" + WordsArrayList2String(MainActivity.GROUPS.get(key)); + } + //將資料寫入 + os.write(saves.getBytes()); + os.close(); + }catch(Exception ex){ + Toast.makeText(this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + finish(); + } + String WordsArrayList2String(ArrayList words){ + String returns = words.get(0); + for(int i=1;i-1){ + //生成一個對話方塊來再次確認是否刪除 + AlertDialog.Builder ad = new AlertDialog.Builder(this); + //設定對話方塊的標題為"確認刪除" + ad.setTitle("確認刪除"); + //設定對話方塊的內容為"確定要刪除群組"[群組名稱]"?" + ad.setMessage("確定要刪除群組\"" + lstGroups.getItemAtPosition(lstGroups.getCheckedItemPosition()) + "\"?"); + //設定當使用者按下對話方塊的正回應按鍵,也就是按下"確定"按鈕時的事件。 + //若使用者按下【確定】,以指定所選的項目,把groups裡的群組名稱與群組內容、arrayAdapter裡的群組名稱刪除。 + ad.setPositiveButton("確定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + try { + MainActivity.GROUPS.remove(groupName); + MainActivity.GROUP_NAMES.remove(index); + MainActivity.groupCount--; + arrayAdapter.notifyDataSetChanged(); + lstGroups.setSelection(-1); + } catch (Exception ex) { + Toast.makeText(ActGrouping.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + }); + //設定當使用者按下對話方塊的負回應按鍵,也就是按下"取消"按鈕時的事件。 + ad.setNegativeButton("取消", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + //顯示對話方塊 + ad.show(); + } + }catch (Exception ex){ + if(ex.getClass().getSimpleName().equals("NullPointerException")) + Toast.makeText(this, "請選擇欲刪除的群組", Toast.LENGTH_SHORT).show(); + else + Toast.makeText(ActGrouping.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //當【編輯群組單字】按鈕按下 + public void btnViewGroupWords_Click(View view) { + try{ + String groupName = lstGroups.getItemAtPosition(lstGroups.getCheckedItemPosition()).toString(); + Intent theIntent = new Intent(this, ActEditingGroup.class); + theIntent.putExtra("groupName", groupName); + startActivityForResult(theIntent, 1); + }catch(Exception ex){ + if(ex.getClass().getSimpleName().equals("NullPointerException")) + Toast.makeText(this, "請選擇欲編輯的群組", Toast.LENGTH_SHORT).show(); + else + Toast.makeText(ActGrouping.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //當下一層的版面關閉後 + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (resultCode){ + case 0: + String theName = data.getStringExtra("NewGroupName"); + if(!theName.equals("$NONE")){ + try{ + ArrayList newArrayList = new ArrayList<>(); newArrayList.add("0"); + MainActivity.GROUPS.put(theName, newArrayList); + MainActivity.GROUP_NAMES.add(theName); + MainActivity.groupCount++; + arrayAdapter.notifyDataSetChanged(); + }catch(Exception ex) { + Toast.makeText(this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + break; + case 1: + //ArrayList groupArray = (ArrayList) data.getExtras().get("groupArray"); + //String groupName = data.getExtras().getString("groupName"); + //groups.put(groupName, groupArray); + break; + } + } + + //Keeps + void keeps(){ + + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActPieceVoca.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActPieceVoca.java new file mode 100755 index 0000000..d83784b --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActPieceVoca.java @@ -0,0 +1,92 @@ +package com.example.leeyuanair.englishhelper.act_allwords; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.AssetManager; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.R; +import com.example.leeyuanair.englishhelper.access.WordInfo; + +import java.io.InputStream; +import java.util.ArrayList; + +public class ActPieceVoca extends AppCompatActivity implements AdapterView.OnItemClickListener { + ArrayList WordsList; + ArrayAdapter arrayAdapter; + //WordsData + WordInfo[] words; + //Button + Button btnBack; + //ListView + ListView lstWords; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_piece_voca); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + //從Intent中解析Bundle + Bundle msg = getIntent().getExtras(); + //鏈結按鈕物件 + btnBack = (Button) findViewById(R.id.btnBack1); + //鏈結清單物件 + lstWords = (ListView) findViewById(R.id.lstWords1); + lstWords.setOnItemClickListener(this); + //設定基本清單數值 + WordsList = new ArrayList(); + arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,WordsList); + //取得於畫面ActAllVaco的lstWords裡所選擇項目,並依照該值取得相符的自首單字。 + String SelectedLetter = msg.getString("SelectedItem"); + readAppointedVoca(SelectedLetter); + setTitle("字首為\""+SelectedLetter+"\"的所有單字"); + } + + //程序: 讀取指定字首的單字,並設定至ListView。 + protected void readAppointedVoca(String letter){ + AssetManager as = getAssets(); + try{ + InputStream is = as.open("Words.txt"); + byte[] data = new byte[is.available()]; + is.read(data); is.close(); + WordsList.addAll(getAppointedVoca(new String(data),letter.toLowerCase())); + arrayAdapter.notifyDataSetChanged(); + lstWords.setAdapter(arrayAdapter); + }catch(Exception ex){ + Toast.makeText(this,ex.toString(),Toast.LENGTH_SHORT).show(); + } + } + //函式: 取得指定字首的字(解析字串),並回傳所選到的字。 + protected ArrayList getAppointedVoca(String data,String targe){ + ArrayList returns = new ArrayList(); + String[] info = (data.replace("\r","")).split("\n"); + String[] spis; + for(int i = 1; i parent, View view, int position, long id) { + Object SelItem = parent.getItemAtPosition(position); + Intent theIntent = new Intent(this,ActWordInfo.class); + theIntent.putExtra("SelectedWord", SelItem.toString()); + theIntent.putExtra("isAddingMode", false); + //theIntent.putExtra("WordsData",words); + startActivity(theIntent); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActWordInfo.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActWordInfo.java new file mode 100755 index 0000000..bfc54b0 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_allwords/ActWordInfo.java @@ -0,0 +1,122 @@ +package com.example.leeyuanair.englishhelper.act_allwords; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.AssetManager; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.view.ViewGroup.LayoutParams; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.io.InputStream; + +public class ActWordInfo extends AppCompatActivity { + //Global Variables + boolean isAddingMode; + String isAdd; + //LinearLayout直式排版元件 + LinearLayout linNoun, linAdjective, linVerb, linAdverb, linPreposition; + //TextView文字標籤元件 + TextView lblWordTitle, lblNoun, lblAdjective, lblVerb, lblAdverb, lblPreposition; + //Button按鈕元件 + Button btnAdd2Addition; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_word_info); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + //取得傳遞的訊息 + Bundle msg = getIntent().getExtras(); + //鏈結橫列表格物件 + linNoun = (LinearLayout) findViewById(R.id.linNoun); + linAdjective = (LinearLayout) findViewById(R.id.linAdjective); + linVerb = (LinearLayout) findViewById(R.id.linVerb); + linAdverb = (LinearLayout) findViewById(R.id.linAdverb); + linPreposition = (LinearLayout) findViewById(R.id.linPreposition); + //鏈結標籤物件 + lblWordTitle = (TextView) findViewById(R.id.lblWordTitle); + lblNoun = (TextView) findViewById(R.id.lblNoun); + lblAdjective = (TextView) findViewById(R.id.lblAdjective); + lblVerb = (TextView) findViewById(R.id.lblVerb); + lblAdverb = (TextView) findViewById(R.id.lblAdverb); + lblPreposition = (TextView) findViewById(R.id.lblPreposition); + //鏈結按鈕物件 + btnAdd2Addition = (Button) findViewById(R.id.btnAdd2Addition); + //判斷是否有選擇單字的功能 + isAddingMode = (boolean) msg.get("isAddingMode"); + LayoutParams btnLayout = btnAdd2Addition.getLayoutParams(); + btnLayout.height = isAddingMode ? btnLayout.height : 0; + btnAdd2Addition.setLayoutParams(btnLayout); + btnAdd2Addition.setEnabled(isAddingMode); + //初始化是否新增該單字的暫存,原設為無值null + isAdd = null; + //取得所選單字 + String SelectedWord = msg.getString("SelectedWord"); + setTitle("單字\""+SelectedWord+"\"的詞性、字義"); + //取得該單字的詞性與字義 + try{ + lblWordTitle.setText(SelectedWord); + String[] pOS = MainActivity.ALL_WORDS.get(SelectedWord); + lblNoun.setText((pOS[0]!=null && !pOS[0].equals("")) ? pOS[0] : ""); + lblAdjective.setText((pOS[1]!=null && !pOS[1].equals("")) ? pOS[1] : ""); + lblVerb.setText((pOS[2]!=null && !pOS[2].equals("")) ? pOS[2] : ""); + lblAdverb.setText((pOS[3]!=null && !pOS[3].equals("")) ? pOS[3] : ""); + lblPreposition.setText((pOS[4]!=null && !pOS[4].equals("")) ? pOS[4] : ""); + //找到使用者所選的單字時,解析該訊息並顯示詞性、字義 + hideLayout(lblNoun.getText().equals(""), linNoun); + hideLayout(lblAdjective.getText().equals(""),linAdjective); + hideLayout(lblVerb.getText().equals(""),linVerb); + hideLayout(lblAdverb.getText().equals(""),linAdverb); + hideLayout(lblPreposition.getText().equals(""),linPreposition); + }catch(Exception ex) { + Toast.makeText(this,"找不到該單字!",Toast.LENGTH_SHORT).show(); + } + } + //影藏Layout的判斷函式 + public void hideLayout(boolean compare,LinearLayout ly){ + if(compare){ + ViewGroup.LayoutParams lay = ly.getLayoutParams(); + lay.height = 0; + ly.setLayoutParams(lay); + } + } + + //返回上一層 + public void btnBack2_onClick(View view) { + Intent theIntent = new Intent(); + if(isAddingMode){ + theIntent.putExtra("isAdd", isAdd); + } + setResult(isAddingMode ? 0 : -1, theIntent); + finish(); + } + + //標示使用者要增加此單字 + public void btnAdd2Addition(View view) { + isAdd = lblWordTitle.getText().toString(); + Toast.makeText(ActWordInfo.this, "已新增單字至群組", Toast.LENGTH_SHORT).show(); + } + + //攔截使用者所按下的按鍵 - 包含返回、家、視窗等等按鍵 + @Override + public boolean onKeyDown(int keyCode, KeyEvent event){ + if(keyCode == KeyEvent.KEYCODE_BACK){ + Intent theIntent = new Intent(); + if(isAddingMode){ + theIntent.putExtra("isAdd", isAdd); + } + setResult(isAddingMode ? 0 : -1, theIntent); + finish(); + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemoryPractice.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemoryPractice.java new file mode 100755 index 0000000..ce05487 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemoryPractice.java @@ -0,0 +1,392 @@ +package com.example.leeyuanair.englishhelper.act_memory; + +import android.app.AlertDialog; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; + +public class ActMemoryPractice extends AppCompatActivity { + //##Global Variable + boolean mode; //練習模式: false表示有限題數, true表示練習至了解為止 + int groupIndex; //使用者所選的群組單字的序號 + int maxQ, Q; //表示指定的練習題數 與 目前題數 + int timelimit; //每題所限制的回答時間(毫秒) + int timecount; //目前的計時 + int delay; //延遲次數(每次1秒) + int width; //表示加上timecount的幅度,功能是與timecount相加 + int backUpTimeCount; //退出練習的確認時間 + ArrayList QuestionList; //題目清單 + LinkedHashMap WrongsList; //「NO」清單,記錄下所有不了解的單字的次數 + HashSet QuickWrongsList; //與「NO」清單類似,只不過此清單只有在「練習至了解所有單字為止」時的模式才會用到 + //TextView文字標籤物件 + TextView lblMemoryStatus, lblQuestion1, lblMemoryHint; + //ProgressBar進度顯示物件 + ProgressBar pgbCountdown2; + //Timer計時器 + Timer countDownTimer; + //AlertDialog對話框物件 + AlertDialog answerShows; + //Random亂數產生器 + Random rnd; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_memory_practice); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("記憶練習"); + //連結文字標籤物件 + lblMemoryStatus = (TextView) findViewById(R.id.lblMemoryStatus); + lblQuestion1 = (TextView) findViewById(R.id.lblQuestion1); + lblMemoryHint = (TextView) findViewById(R.id.lblMemoryHint); + //連結進度顯示物件 + pgbCountdown2 = (ProgressBar) findViewById(R.id.pgbCountdown2); + pgbCountdown2.setMax(1000); + //初始化對話方塊 + answerShows = (new AlertDialog.Builder(this)).create(); + answerShows.setCancelable(false); + //初始化NO清單 + WrongsList = new LinkedHashMap<>(); + //初始化亂數產生器 + rnd = new Random(); + //取得資料 & 初始化 + Bundle msg = getIntent().getExtras(); + mode = msg.getBoolean("mode"); + timelimit = msg.getInt("timelimit"); + groupIndex = msg.getInt("Selection"); + //若模式為練習到了解為止.. + if (mode) { + QuestionGenerator(1); + QuickWrongsList = new HashSet<>(); + } else { + maxQ = msg.getInt("questions"); + QuestionGenerator(maxQ); + } + Q = 0; //初始化題目計數 + timecount = 0; //初始化計時 + delay = 4; //初始化延遲次數 + width = 1; + //初始化計時系統Timer + countDownTimer = new Timer(); + countDownTimer.schedule(countDownTask, 0, 1); + } + + //####題目生成器#### + void QuestionGenerator(int questionAmount){ + try { + ArrayList sourceGroup = ((groupIndex >= 0) ? MainActivity.GROUPS.get(MainActivity.GROUP_NAMES.get(groupIndex)) : MainActivity.WORDS); + QuestionList = new ArrayList(); + for (int i = 1; i <= (questionAmount / sourceGroup.size()) + 1; i++) + QuestionList.addAll(RandomizeList(sourceGroup)); + }catch(Exception ex){ + Toast.makeText(ActMemoryPractice.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + //函式 - 回傳新的已打亂過的清單內容 + ArrayList RandomizeList(ArrayList list) { + ArrayList rndList = (ArrayList) list.clone(); + try { + String temp; + int num; + //利用rnd亂數產生器打亂原本的排列 + for (int i = rndList.size() - 1; i >= 0; i--) { + num = rnd.nextInt(i + 1); + temp = rndList.get(num); + rndList.set(num, rndList.get(i)); + rndList.set(i, temp); + } + } catch (Exception ex) { + Toast.makeText(ActMemoryPractice.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + return rndList; + } + //####快速題目生產器#### + void RapidQuestionGenerator(String word ,int value){ + if(!QuestionList.contains(word)){ + ArrayList sourceGroup = ((groupIndex>=0) ? MainActivity.GROUPS.get(MainActivity.GROUP_NAMES.get(groupIndex)) : MainActivity.WORDS); + ArrayList rndList = new ArrayList<>(RandomizeList(sourceGroup)); + //若使用者所選的單字群組的單字量小於10: 為了避免在隨機選取的次數上發生問題,也就是隨機排列後的群組單字量不夠,這裡再增加一組的隨機的單字量 + if(sourceGroup.size()<10) + rndList.addAll(RandomizeList(sourceGroup)); + for(int i=0;i WrongsList; + Object[] WrongsWordsArray; + ArrayAdapter WrongsAdapter; + //TextView文字標籤物件 + TextView lblQuestionAmount2; + TextView lblNotUnderstandText1; + //ListView清單物件 + ListView lstNotUnderstandList; + //AlertDialog對話框物件 + AlertDialog.Builder msgBox; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_memory_result); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("記憶練習 - 練習結果"); + try { + //連結文字標籤物件 + lblQuestionAmount2 = (TextView) findViewById(R.id.lblQuestionAmount2); + lblNotUnderstandText1 = (TextView) findViewById(R.id.lblNotUnderstandText1); + //連結清單物件 + lstNotUnderstandList = (ListView) findViewById(R.id.lstNotUnderstandList); + lstNotUnderstandList.setOnItemClickListener(this); + //初始化對話框物件 + msgBox = new AlertDialog.Builder(this); + msgBox.setTitle("單字訊息"); + msgBox.setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }); + //取得結果資料 + Bundle msg = getIntent().getExtras(); + questions = msg.getInt("questions"); + lblQuestionAmount2.setText(String.valueOf(questions)); + WrongsList = (HashMap) msg.get("WrongsList"); + //初始化清單物件變數 + if(WrongsList.isEmpty()){ + lblNotUnderstandText1.setText("Good Job! 你已經記起所有的單字了!"); + }else{ + WrongsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); + WrongsWordsArray = WrongsList.keySet().toArray(); + for (Object word : WrongsWordsArray) + WrongsAdapter.add(word.toString() + " ,次數: " + WrongsList.get(word)); + lstNotUnderstandList.setAdapter(WrongsAdapter); + } + }catch(Exception ex){ + Toast.makeText(ActMemoryResult.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //當清單lstWrongsList某項目被按下時 + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String[] partOfSpeech = MainActivity.ALL_WORDS.get(WrongsWordsArray[position]); + msgBox.setMessage(WrongsWordsArray[position] + + ((partOfSpeech[0]!=null) ? "\r\n名詞(n.) "+partOfSpeech[0] : "") + + ((partOfSpeech[1]!=null) ? "\r\n形容詞(adj.) "+partOfSpeech[1] : "") + + ((partOfSpeech[2]!=null) ? "\r\n動詞(adj.) "+partOfSpeech[2] : "") + + ((partOfSpeech[3]!=null) ? "\r\n副詞(adj.) "+partOfSpeech[3] : "") + + ((partOfSpeech[4]!=null) ? "\r\n介係詞(adj.) "+partOfSpeech[4] : "")); + msgBox.show(); + } + + //當【返回至設定頁面】按鈕按下時 + public void btnBack7_Click(View view) {finish();} + +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemorySetting.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemorySetting.java new file mode 100755 index 0000000..06dbcb0 --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_memory/ActMemorySetting.java @@ -0,0 +1,192 @@ +package com.example.leeyuanair.englishhelper.act_memory; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.graphics.Color; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.RadioButton; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; + +public class ActMemorySetting extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { + //Global Variable全域變數 + boolean qualified; //表示所選群組是否符合最低要求(單字量>4) + int selection; //表示使用者所選擇的群組號 + boolean soManyWordsNotice; // 若是用者在了解模式下選擇超過100個單字的單字群組時所判別是否要提醒使用者的變數 + //Button按鈕物件 + Button btnChangeGroup2; + //EditText文字編輯物件 + EditText txtQAmount2; + //TextView文字標籤物件 + TextView lblTimePerQ2; + TextView lblExtraMsg2; + //RadioButton單選按鈕物件 + RadioButton rdoKeepPractice, rdoQuestions; + //SeekBar滑桿元件 + SeekBar skbTimeSet2; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_memory_setting); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("記憶練習"); + //連結按鈕物件 + btnChangeGroup2 = (Button) findViewById(R.id.btnChangeGroup2); + //連結文字編輯物件 + txtQAmount2 = (EditText) findViewById(R.id.txtQAmount2); + //連結文字標籤物驗 + lblTimePerQ2 = (TextView) findViewById(R.id.lblTimePerQ2); + lblExtraMsg2 = (TextView) findViewById(R.id.lblExtraMsg2); + //連結單選按鈕物件 + rdoKeepPractice = (RadioButton) findViewById(R.id.rdoKeepPractice); + rdoQuestions = (RadioButton) findViewById(R.id.rdoQuestions); + //連結華感物件 + skbTimeSet2 = (SeekBar) findViewById(R.id.skbTimeSet2); + skbTimeSet2.setOnSeekBarChangeListener(this); + //初始化變數 + qualified=true; + soManyWordsNotice = true; + selection=-1; + } + + //當按鈕btnChangeGroup2 更換群組按鈕按下時 + public void btnChangeGroup2_Click(View view) { + final ArrayAdapter groupNames = new ArrayAdapter(this,android.R.layout.simple_list_item_1); + groupNames.add("所有單字"); groupNames.addAll(MainActivity.GROUP_NAMES); + AlertDialog.Builder msgBox = new AlertDialog.Builder(this) + .setTitle("選擇群組") + .setAdapter(groupNames, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + btnChangeGroup2.setText(groupNames.getItem(which)); + selection=which-1; + if(which>0){ + ArrayList SelGroup = MainActivity.GROUPS.get(groupNames.getItem(which)); + if(SelGroup.size()<4) { + lblExtraMsg2.setText("群組內的單字量必須大於4個才能開始練習!"); + lblExtraMsg2.setTextColor(Color.RED); + soManyWordsNotice=false; + qualified = false; + }else if(SelGroup.size()>100){ + if(rdoKeepPractice.isChecked()) + lblExtraMsg2.setText("此單字群組的單字量大於100個,若要練習到完可能需要花較長的時間!"); + else + lblExtraMsg2.setText(""); + qualified=true; + soManyWordsNotice=true; + }else{ + lblExtraMsg2.setText(""); + qualified = true; + soManyWordsNotice=false; + } + }else{ + if(rdoKeepPractice.isChecked()) + lblExtraMsg2.setText("此單字群組的單字量大於100個,若要練習到完可能需要花較長的時間!"); + soManyWordsNotice=true; + lblExtraMsg2.setText(""); + qualified = true; + } + } + }); + msgBox.show(); + } + + //當【-】按鈕按下時 + public void btnSubtract2_Click(View view) { + int num = Integer.parseInt(txtQAmount2.getText().toString()) - 1; + txtQAmount2.setText(String.valueOf(num > 0 ? num : 1)); + } + + //當【+】按鈕按下時 + public void btnAdd2_Click(View view) { + int num = Integer.parseInt(txtQAmount2.getText().toString()) + 1; + txtQAmount2.setText(String.valueOf(num < 10000 ? num : 9999)); + } + + //當【練習到每個單字了解為止】單選按鈕按下時 + public void rdoKeepPractice_Click(View view) { + rdoKeepPractice.setChecked(true); + rdoQuestions.setChecked(false); + if(soManyWordsNotice) + lblExtraMsg2.setText("此單字群組的單字量大於100個,若要練習到完可能需要花較長的時間!"); + } + + //當【依指定題數練習】單選按鈕按下時 + public void rdoQuestions_Click(View view) { + rdoKeepPractice.setChecked(false); + rdoQuestions.setChecked(true); + if(soManyWordsNotice) + lblExtraMsg2.setText(""); + } + + //當【返回】按鈕按下時 + public void btnBack6_Click(View view) { + finish(); + } + + //當【說明】按鈕按下時 + public void btnExplanation2_Click(View view) { + final AlertDialog.Builder adExp1, adExp2, adExp3; + adExp3 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("關於設定的部分,你可以選擇單字群組、設定題目數量與每題答題時間," + + "練習模式可以選擇「練習到每個了解為止」、「依指定題數練習」這兩種方式。" + + "完成設定之後就可以開始練習了!") + .setPositiveButton("OK", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + adExp2 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("如果知道該單字的意思的話,按下YES按鈕表示了解;若不知道該單字的意思," + + "則按下NO表示不了解,每按一次NO系統就會記錄下一次。如果你所選的模式是練習到會為止," + + "則系統也會一直持續記錄到完成為止。(雖然如此,因為有限性的關係,所以至多系統也只會到9999題為止)") + .setPositiveButton("下一頁", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {adExp3.show();}}); + adExp1 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("由於字義選擇的四選一題目可以透過辨識選項的方式來答題," + + "所以這可能無法完全檢視自己是否了解、熟悉該單字,因此,在記憶練習中除了會照常出題之外" + + "這裡將四選項改成了YES、NO按鈕。") + .setPositiveButton("下一頁", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {adExp2.show();}}); + adExp1.show(); + } + + //當【開始練習】按鈕按下時 + public void btnStartTest2_Click(View view) { + if (qualified) { + Intent it = new Intent(this, ActMemoryPractice.class); + it.putExtra("Selection", selection); + it.putExtra("mode", rdoKeepPractice.isChecked()); + if (rdoQuestions.isChecked()) + it.putExtra("questions", Integer.parseInt(txtQAmount2.getText().toString())); + it.putExtra("timelimit", skbTimeSet2.getProgress() * 1000); + startActivity(it); + } + + } + + //##SeekBar滑桿物件的事件處理副程式## + //當滑桿滑動時 + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if(progress>0) + lblTimePerQ2.setText("每題答題時間: "+progress+"秒"); + else + lblTimePerQ2.setText("每題答題時間: 無限制"); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} + //##################################### +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingExamine.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingExamine.java new file mode 100755 index 0000000..a3afe1a --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingExamine.java @@ -0,0 +1,215 @@ +package com.example.leeyuanair.englishhelper.act_spelling; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; +import java.util.Random; + +public class ActSpellingExamine extends AppCompatActivity { + //Global Variables + int groupIndex; //所選的單字群組的編號 + int maxQ, Q; //總題數, 目前題號 + boolean prefix, suffix; //是否啟用字首、字尾提示 + int rights; //答對題數 + ArrayList QuestionList; //題目清單 + ArrayList UserAnswerList; //使用者的回答清單 + //LinearLayout直線型排版容器 + LinearLayout[] linPartOfSpeech; + //TextView文字標籤元件 + TextView[] lblPartOfSpeech; + TextView lblSpellingStatus1; + TextView lblSpellingStatus2; + TextView lblQuestionMessage; + //EditText文字編輯元件 + EditText txtAnswerBar; + //AlertDialog對話框物件 + AlertDialog.Builder response; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_spelling_examine); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("拼字測驗"); + //##連結直線型排版容器 並 初始化陣列 + try { + linPartOfSpeech = new LinearLayout[5]; + linPartOfSpeech[0] = (LinearLayout) findViewById(R.id.linQNoun); + linPartOfSpeech[1] = (LinearLayout) findViewById(R.id.linQAdjective); + linPartOfSpeech[2] = (LinearLayout) findViewById(R.id.linQVerb); + linPartOfSpeech[3] = (LinearLayout) findViewById(R.id.linQAdverb); + linPartOfSpeech[4] = (LinearLayout) findViewById(R.id.linQPreposition); + //##連結文字標籤元件 並 初始化陣列 + lblPartOfSpeech = new TextView[5]; + lblPartOfSpeech[0] = (TextView) findViewById(R.id.lblQNoun); + lblPartOfSpeech[1] = (TextView) findViewById(R.id.lblQAdjective); + lblPartOfSpeech[2] = (TextView) findViewById(R.id.lblQVerb); + lblPartOfSpeech[3] = (TextView) findViewById(R.id.lblQAdverb); + lblPartOfSpeech[4] = (TextView) findViewById(R.id.lblQPreposition); + lblSpellingStatus1 = (TextView) findViewById(R.id.lblSpellingStatus1); + lblSpellingStatus2 = (TextView) findViewById(R.id.lblSpellingStatus2); + lblQuestionMessage = (TextView) findViewById(R.id.lblQuestionMessage); + //##連結文字編輯元件 + txtAnswerBar = (EditText) findViewById(R.id.txtAnswerBar); + //##初始化對話框 + response = new AlertDialog.Builder(this); + response.setCancelable(false); + response.setPositiveButton("OK", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + //取得資料 + Bundle msg = getIntent().getExtras(); + groupIndex = msg.getInt("selection"); + maxQ = msg.getInt("questions"); + prefix = msg.getBoolean("prefix"); + suffix = msg.getBoolean("suffix"); + //建立題目清單 + QuestionGenerator(); + //初始化 + UserAnswerList = new ArrayList<>(); + Q = 0; + rights = 0; + lblSpellingStatus1.setText("總題目: " + maxQ + ", 目前題號: 1"); + AnaliysisQuestion(); + //預備的對話框 + AlertDialog.Builder msgBox = new AlertDialog.Builder(this) + .setTitle("預備") + .setMessage("若輸入文字時會出現提示字的話,建議先關閉此項功能!" + + "按下「Start」即可開始測驗。") + .setCancelable(false) + .setPositiveButton("Start", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }); + msgBox.show(); + }catch(Exception ex){ + Toast.makeText(ActSpellingExamine.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //程序 - 題目生成器 + void QuestionGenerator(){ + QuestionList = new ArrayList<>(); + ArrayList sourceGroup = (groupIndex>=0) ? MainActivity.GROUPS.get(MainActivity.GROUP_NAMES.get(groupIndex)) : MainActivity.WORDS; + for(int i=1;i<=(maxQ/sourceGroup.size())+1;i++) + QuestionList.addAll(randomizeGroup(sourceGroup)); + } + //題目生成器 -> 函式 - 回傳打亂過的新的清單 + ArrayList randomizeGroup(ArrayList sourceGroup){ + ArrayList rndList = (ArrayList) sourceGroup.clone(); + Random rnd = new Random(); rnd.setSeed(rnd.nextInt(100)); + String temp; int num; + for(int i=rndList.size()-1;i>0;i--){ + num = rnd.nextInt(i+1); + temp = rndList.get(num); + rndList.set(num, rndList.get(i)); + rndList.set(i, temp); + } + return rndList; + } + + //程序 - 解析題目中的單字 + void AnaliysisQuestion(){ + String word = QuestionList.get(Q); + String[] partOfSpeech = MainActivity.ALL_WORDS.get(word); + for(int i=0;i<5;i++){ + if(partOfSpeech[i]!=null){ + ViewGroup.LayoutParams lay = linPartOfSpeech[i].getLayoutParams(); + lay.height=180; + linPartOfSpeech[i].setLayoutParams(lay); + lblPartOfSpeech[i].setText(partOfSpeech[i]); + }else{ + ViewGroup.LayoutParams lay = linPartOfSpeech[i].getLayoutParams(); + lay.height=0; + linPartOfSpeech[i].setLayoutParams(lay); + } + } + lblQuestionMessage.setText("#此單字長度為"+word.length()+",有以下詞性意義:"); + //依條件來生成提示 + txtAnswerBar.setHint((prefix ? word.charAt(0) : "_")+"_____________"+((suffix && word.length()>4) ? word.charAt(word.length()-1) : "_")); + } + + //當【提交答案】按鈕按下時 + public void btnAnswerIt_Click(View view) { + // 隱藏螢幕鍵盤 + InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + try { + //將使用者的答案增加至UserAnswerList中 + UserAnswerList.add(txtAnswerBar.getText().toString().trim()); + if (QuestionList.get(Q).equals(UserAnswerList.get(Q))) { + rights++; + response.setTitle("答案正確!"); + response.setMessage(QuestionList.get(Q)); + } else { + response.setTitle("答案錯誤!"); + response.setMessage("正確答案: " + QuestionList.get(Q) + + "\r\n你的答案: " + UserAnswerList.get(Q)); + } + //題目序號+1 + Q++; + //如果還有題目的話 + if (Q < maxQ) { + //更新題目 + AnaliysisQuestion(); + txtAnswerBar.setText(""); + //更新狀態 + lblSpellingStatus2.setText("總題目: " + maxQ + ", 目前題號: " + (Q + 1)); + lblSpellingStatus1.setText("答對題數: " + rights + ", 答錯題數: " + (Q - rights)); + } else { + response.setPositiveButton("測驗完成", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent it = new Intent(ActSpellingExamine.this, ActSpellingResult.class); + it.putExtra("maxQ", maxQ); + it.putExtra("rights", rights); + it.putExtra("QuestionList", QuestionList); + it.putExtra("UserAnswerList", UserAnswerList); + startActivityForResult(it, 0); + } + }); + } + response.show(); + }catch(Exception ex){ + Toast.makeText(ActSpellingExamine.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //當下一層的頁面關閉時 + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + finish(); + } + + //攔截使用者所按下的按鍵 - 包含返回、家、視窗等等按鍵 + @Override + public boolean onKeyDown(int keyCode, KeyEvent event){ + if(keyCode == KeyEvent.KEYCODE_BACK){ + AlertDialog.Builder checker = new AlertDialog.Builder(this) + .setTitle("確定離開測驗?") + .setMessage("若中途離開此測驗將看不到所測的結果。") + .setPositiveButton("Yes", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {finish();}}) + .setNegativeButton("No", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + checker.show(); + return true; + } + return super.onKeyDown(keyCode, event); + } + + +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingResult.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingResult.java new file mode 100755 index 0000000..14c0fae --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingResult.java @@ -0,0 +1,80 @@ +package com.example.leeyuanair.englishhelper.act_spelling; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.pm.ActivityInfo; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; + +public class ActSpellingResult extends AppCompatActivity implements ListView.OnItemClickListener{ + //Global Variables + ArrayList QuestionList; + ArrayList UserAnswerList; + //ListView清單元件 + ListView lstAnswerLog2; + //AlertDialog對話框元件 + AlertDialog.Builder msgBox; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_spelling_result); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("拼字測驗 - 測驗結果"); + //##連結清單元件 + lstAnswerLog2 = (ListView) findViewById(R.id.lstAnswerLog2); + lstAnswerLog2.setOnItemClickListener(this); + //##初始化對話框物件 + msgBox = new AlertDialog.Builder(this) + .setPositiveButton("OK", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + //##取得結果資料 + Bundle msg = getIntent().getExtras(); + //利用變數傳址的方法來立即地修改元件屬性 + ((TextView) findViewById(R.id.lblQuestionAmount3)).setText(String.valueOf(msg.getInt("maxQ"))); + ((TextView) findViewById(R.id.lblRights2)).setText(String.valueOf(msg.getInt("rights"))); + ((TextView) findViewById(R.id.lblWrongs2)).setText(String.valueOf(msg.getInt("maxQ") - msg.getInt("rights"))); + //取得問題清單 及 使用者回答結果 + QuestionList = (ArrayList) msg.get("QuestionList"); + UserAnswerList = (ArrayList) msg.get("UserAnswerList"); + ArrayAdapter logAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); + try { + for (int i = 0; i < UserAnswerList.size(); i++) { + logAdapter.add((QuestionList.get(i).equals(UserAnswerList.get(i)) ? "O " : "X ") + + (i + 1) + ". " + QuestionList.get(i)); + } + lstAnswerLog2.setAdapter(logAdapter); + }catch(Exception ex){ + Toast.makeText(ActSpellingResult.this, ex.toString(), Toast.LENGTH_SHORT).show(); + } + } + + //當lstAnswerLog2內的清單項按下時 + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String word = QuestionList.get(position); + String[] partOfSpeech = MainActivity.ALL_WORDS.get(word); + boolean isRight = (word.equals(UserAnswerList.get(position))); + msgBox.setTitle(isRight ? "此題答對" : "此題答錯"); + msgBox.setMessage("正確答案: "+word+(isRight ? "\r\n" : "\r\n你的答案: "+UserAnswerList.get(position)+"\r\n") + + (partOfSpeech[0]!=null ? "\r\n名詞(n.) "+partOfSpeech[0] : "") + + (partOfSpeech[1]!=null ? "\r\n形容詞(adj.) "+partOfSpeech[1] : "") + + (partOfSpeech[2]!=null ? "\r\n動詞(v.) "+partOfSpeech[2] : "") + + (partOfSpeech[3]!=null ? "\r\n副詞(adv.) "+partOfSpeech[3] : "") + + (partOfSpeech[4]!=null ? "\r\n介係詞(prep.) "+partOfSpeech[4] : "")); + msgBox.show(); + } + + //當【返回至設定頁面】按鈕按下時 + public void btnBack9_Click(View view) {finish();} + +} diff --git a/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingSetting.java b/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingSetting.java new file mode 100755 index 0000000..9337b9c --- /dev/null +++ b/app/src/main/java/com/example/leeyuanair/englishhelper/act_spelling/ActSpellingSetting.java @@ -0,0 +1,164 @@ +package com.example.leeyuanair.englishhelper.act_spelling; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.graphics.Color; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.TextView; + +import com.example.leeyuanair.englishhelper.MainActivity; +import com.example.leeyuanair.englishhelper.R; + +import java.util.ArrayList; + +public class ActSpellingSetting extends AppCompatActivity { + //Global Variables + int selection; //紀錄使用者所選擇的群組的編號 + boolean qualified; //表示所選的單字群組是否符合基本要求(單字量大於4個) + //Button按鈕元件 + Button btnChangeGroup3; + //TextView文字標籤元件 + TextView lblExtraMsg3; + //EditText文字編輯元件 + EditText txtQAmount3; + //CheckBox勾選元件 + CheckBox chkPrefix, chkSuffix; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_act_spelling_setting); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + setTitle("拼字測驗 - 測驗設定"); + //連結按鈕元件 + btnChangeGroup3 = (Button) findViewById(R.id.btnChangeGroup3); + //連結文字標籤元件 + lblExtraMsg3 = (TextView) findViewById(R.id.lblExtraMsg3); + //連結文字編輯元件 + txtQAmount3 = (EditText) findViewById(R.id.txtQAmount3); + //連結勾選元件 + chkPrefix = (CheckBox) findViewById(R.id.chkPrefix); + chkSuffix = (CheckBox) findViewById(R.id.chkSuffix); + //初始化變數 + selection=-1; + qualified=true; + } + + //當btnChangeGroup3按鈕按下時 + public void btnChangeGroup3_Click(View view) { + final ArrayList ad = new ArrayList(); + ad.add("所有單字"); ad.addAll(MainActivity.GROUP_NAMES); + AlertDialog.Builder alert = new AlertDialog.Builder(this) + .setTitle("選擇群組") + .setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, ad), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + selection=which-1; + btnChangeGroup3.setText(ad.get(which)); + if(selection>=0){ + ArrayList SelGroup = MainActivity.GROUPS.get(MainActivity.GROUP_NAMES.get(selection)); + qualified=SelGroup.size()>4; + if(qualified){ + lblExtraMsg3.setTextColor(Color.argb(255,168,168,168)); + if(chkSuffix.isChecked() || chkPrefix.isChecked()){ + lblExtraMsg3.setText("如果某項單字長度小於5的話,題目只會提供字首或不提供"); + }else{ + lblExtraMsg3.setText(""); + } + }else{ + lblExtraMsg3.setTextColor(Color.RED); + lblExtraMsg3.setText("單字群組內的單字量必須大於4個。"); + } + }else{ + qualified=true; + lblExtraMsg3.setTextColor(Color.argb(255,168,168,168)); + if(chkSuffix.isChecked() || chkPrefix.isChecked()){ + lblExtraMsg3.setText("如果某項單字長度小於5的話,題目只會提供字首或不提供"); + }else{ + lblExtraMsg3.setText(""); + } + } + } + }); + alert.show(); + } + + //當【+】按鈕按下時 + public void btnAdd3_Click(View view) { + int num = Integer.parseInt(txtQAmount3.getText().toString()) + 1; + txtQAmount3.setText(String.valueOf(num<10000 ? num : 9999)); + } + + //當【-】按鈕按下時 + public void btnSubtract3_Click(View view) { + int num = Integer.parseInt(txtQAmount3.getText().toString()) - 1; + txtQAmount3.setText(String.valueOf(num>0 ? num : 1)); + } + + //當【字首提示】勾選元件按下時 + public void chkPrefix_Click(View view) { + if(qualified){ + if(chkSuffix.isChecked() || chkPrefix.isChecked()){ + lblExtraMsg3.setText("如果某項單字長度小於5的話,題目只會提供字首或不提供"); + }else{ + lblExtraMsg3.setText(""); + } + } + } + + //當【字尾提示】勾選元件按下時 + public void chkSuffix_Click(View view) { + if(qualified){ + if(chkSuffix.isChecked() || chkPrefix.isChecked()){ + lblExtraMsg3.setText("如果某項單字長度小於5的話,題目只會提供字首或不提供"); + }else{ + lblExtraMsg3.setText(""); + } + } + } + + //當【開始測驗】按鈕按下時 + public void btnStartTest3_Click(View view) { + if(qualified){ + Intent it = new Intent(this, ActSpellingExamine.class); + it.putExtra("selection", selection); + it.putExtra("questions", Integer.valueOf(txtQAmount3.getText().toString())); + it.putExtra("prefix", chkPrefix.isChecked()); + it.putExtra("suffix", chkSuffix.isChecked()); + startActivity(it); + } + } + + //當【說明】按鈕按下時 + public void btnExplanation3_Click(View view) { + final AlertDialog.Builder adExp1, adExp2, adExp3; + adExp3 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("在設定的部分,你可以選擇單字群組、設定題目數量與是否提示字首、字尾。" + + "由於每個英文單字的長短個不同,因此次測驗不設置限時選項。設定完之後就可以開始進行測驗了。") + .setPositiveButton("完成", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {}}); + adExp2 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("測驗時只要針對題目所示的詞性意思來寫出正確的英文單字即可。" + + "若有字首或字尾的單字提示,在回答時仍須將其寫出。") + .setPositiveButton("下一頁", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {adExp3.show();}}); + adExp1 = new AlertDialog.Builder(this) + .setTitle("說明") + .setMessage("除了了解單字字義之外,英文的拼寫也是相當地重要。在此測驗中," + + "系統會隨機選擇群組中的單字並秀出其所有的詞性意思。") + .setPositiveButton("下一頁", new DialogInterface.OnClickListener() {@Override public void onClick(DialogInterface dialog, int which) {adExp2.show();}}); + adExp1.show(); + } + + //當【返回】按鈕按下時 + public void btnBack7_Click(View view) {finish();} + +} diff --git a/app/src/main/res/Test.txt b/app/src/main/res/Test.txt new file mode 100755 index 0000000..d800886 --- /dev/null +++ b/app/src/main/res/Test.txt @@ -0,0 +1 @@ +123 \ No newline at end of file diff --git a/app/src/main/res/drawable/drawable.xml b/app/src/main/res/drawable/drawable.xml new file mode 100755 index 0000000..ea2eee6 --- /dev/null +++ b/app/src/main/res/drawable/drawable.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/icon.png b/app/src/main/res/drawable/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..82574c2e25e3e7dec3e93c6671b8f25b75515e8e GIT binary patch literal 2158 zcmeHI`!^K&7XOaNkc{cvIC+~?NFkNH29rm))r5v2VQ}JjIUVognT#Sc28EI_HJUK5>zsA&TKC?y&bsFhIBV^-_THcU+28fupZ&wma6vo5 zj!shyM=j0XKD=I0cRM$Ldq&Bs7 zbawaj4GfRcU%z3_yj@uQu*~7|);9#gXTAR{0|4siY=0D!FuBZl@4X$X2<7D0rYW5> z2(6MUks<{=jtKuoUz(yIrMh=#@ykYj(9-CjA-Csin(e;AOHm6$=5yROEsd2QVv+}} z`!oWT)1yfN&z&c1jdg{7m8UE!EWO&ZFY_EjQH-wXN>7>4T^kT651g>nL&9*82pI}W zi53_9;hbe71jDU`tv&_WZbse`BOm&^&`}Un>ArU*J}|I#-AwL+DJ1)};Th=2$DzLH zTKS@h?Od&m%MbNUk;7cJB*$u)>rqJ_R_H3QUZtX9bExz$W2>_kC3W>4d5eAL>to1y z9F1|$b5$9g;Ra}4I@>e&Gu}`=rdJ=`(ww$yAua@Q)sE7vZXIG?KV_dkq4%}P=2=X< zIYy?I+Af)2F=zIP+;bP}`BUl3u=qSF7F;!OfHSL^SvYyyFmRvd51)n^$2ye9DVPEBf9fUpvo=dUP^-wYb(Hb^Mrb=*_>pDhtNzLlWLt~{in+x}NCNX1=gD9dA`WLaqw=DQW1Y-cDP_1Ll5tgb zjCYZp5!3Ao8wq2Ys9$JHlhwqqZ;}MbBRw5FK!Rp2_{#uR-%+jU2AQnGQQq`hqcgo* zX)B^+X7{ZlHzYD7$%i4GQxM^&VT5cdYoTV+3hty{zW6K0_Ux`{q-fXL@=WmZJy{*t z7`MDAK}*{e@9#-^uLaxF*h{!$3vypUqE1#454$G@-^XL+fj&Fi@Ai_Gx2l3vekw?C zZxg%ri5_diU6iCb{4&1LVS7lFgTTBfTue29MfoVx$Zh(}ZO|;yXP0{y#0ieyvL2by zn)ag{)M?~an-*;aFrh_C+6|9#UG>c}f+IF+*X}2Zse88^cmP;-&MB{yKw{$Jp+ajL z6BCokd_qle>@)^&`nFQu&Whl8cJ?UJIkS@ACXsSV%ylHplus2LUsBxJ#Fmi*QJjzm zaN^N*Ukf$c6AWy+;&LzfH-F)EiSz;uhIHcC`&_#MO@Aw>7jJE%Fw(t-RjqXxq9q~8ehac^g%)i$Rf0ByhI=1@A(&BqD^ znI{$#ClwII)!HfSs*y|Mk!9CwD6%y9^j1l$OFLq^$LUfy^!YM^3NF(PtCaHI`bjIh zz@%dLgK9$%c#JLJ4-dvXbl!I}_9;a9B{6m|%)g(4Ry=tpqnrXq%>B7Uy~t(~*r5o* zog`M*KLdAXP_GX^pf7hozfErHV4YVMQ~K^UsNR&~a=Ur>{nOOCeXqpxdrJ`v_hMdr zkma?^g8fzD-!WRSRu9XBwVg@4AA;?+{MDsw%9;%@1u%ETs}qc~C*{cz`-9@~CdOwQ z9_KO!>77v%-2ri?*zFzX)cznu{|`YW*t{j9bbuXXjB)*=G|qoMH_V<74WM2NG;YqP zWX#ktd)H+Wq}V52oeSNS--dA)$M1KPgY7MJ=j@MZK# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/redngreen.png b/app/src/main/res/drawable/redngreen.png new file mode 100755 index 0000000000000000000000000000000000000000..a4ba453045d320cd60598709a4918d00d63fc616 GIT binary patch literal 10550 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 + + + + + + + +