Androidアプリたたは無題のプロゞェクトを䜜成する

背景


ある晎れた日、私は英語を孊び始めるこずを決め、勉匷する盎前にこの蚀語を教えおいる先生ず盞談したした。 私は圌がか぀お埗た経隓を私ず共有するず思った。 その結果、䞻に英語のサむトを蚪れたずきに知識を䜿甚しおから文法を取り䞊げるので、私は蚀語の蚀葉で勉匷を始めるのが最善であるず圌に同意したした。 圌は少なくずも私にずっお非垞に興味深い勉匷方法を提案したした。 あるずき、蚀葉を芚えおおくために、圌は普通の玙を取り、それを片偎で等しい長方圢に䞊べお切り取り、その長方圢の片偎に英語の単語を曞き、もう片方の翻蚳で、その埌に箱を取り、結果のカヌドをそこに入れお、䞀぀䞀぀混ぜお取り陀き、単語を芋お翻蚳を蚀いたした。
この手順を毎日1〜2時間、定期的に実行し、ファむルキャビネットを補充するず、蚀葉がよく芚えられたす。

それ以来、私は垞にそうするこずを決め、近い将来、自分のように英語で読み始めるようになりたした しかし、しばらくしお、私はカヌドを切っお時間を無駄にするこずに飜き始めたした、同時に、私は垞に絶察に欠けおいたした、その瞬間、私は思考に打たれたした、Android OS甚のプログラムを䜜成しおみたせんかこのシステムで、同様の機胜を実行したす

プロゞェクトが始たったのはこの瞬間からでしたが、名前は思い぀きたせんでした。

目的


このプロゞェクトの目暙は、圓初、ファむルキャビネットぞの単語の远加ずそのさらなる掻甚を自動化するこずでしたが、埌にいく぀かのアむデアが蚪れ、プロゞェクトを開発するこずは非垞に興味深いものでしたが、2週間埌には退屈になり、以前のすべおず同様に退屈し、完党に攟棄したした、私はそうしたくなかったので、この蚘事の著者ずしお自分自身を詊しお、ネットワヌクプログラミングずAndroidのプログラミングの分野での経隓を共有するこずにしたした。 この蚘事では、可胜な限り、このプログラムを䜜成するための手順党䜓をステップごずに説明しようずしたす。

プログラム


たず、私が䜜成した補品の詳现を説明し、機胜を怜蚎したす。その埌、興味がある人は誰でもこの奇跡の䜜成に぀いおさらに読むこずができたす。

説明


私が最初に䌝えたいこずは、メニュヌに぀いおです。できるだけ魅力的なものにしようずしたした。私はい぀も「玠晎らしい」味をしおいたので、これがそれから来たものです。

画像

画像でわかるように、特別なこずは䜕もありたせんが、「蚀葉を確認」たたは「蚀葉」ボタンをクリックするず、いわばサブメニュヌが衚瀺されたす。

画像

画像

䞊の画像からわかるように、「アルファベット順」、「逆順」、「ランダム」の各ボタンには同じプロパティがありたす。 すべお特別な「+」蚘号でマヌクし、開くず蚘号が「-」に眮き換えられたす。 展開されたメニュヌのいずれかのアむテムをクリックするず、元の䜍眮に折りたたたれたす。

テストに合栌する前、たたは単語を倉曎および削陀する前に、単語を远加する必芁がありたす。そのため、このメカニズムを怜蚎したすが、その前にこのトピックから少し戻っおすべおが明確になるようにする必芁がありたす。

私が蚀ったように、プロゞェクトを䜜成する前に、倚くのアむデアが蚪れたしたが、その1぀は、プログラムに単語を远加するこずの簡玠化です。 人が怠zyな生き物であり、誰もが手動でファむルキャビネットを手動で䜜成する必芁があるわけではありたせん。特に、むンタヌネットの発展ず長距離でのデヌタ転送の時代に、3぀のフィヌルドを入力する必芁がある堎合は転写を蚘入する必芁はありたせん

画像

アむデアが思い浮かびたした。プログラムのナヌザヌが自分のファむルキャビネットを党䞖界ず共有しおみたせんか。 したがっお、単語を自分の個人蟞曞に远加する瞬間に、ナヌザヌは気づかないうちにむンタヌネット接続がある堎合サヌバヌにアップロヌドし、デヌタベヌスに保存され、他のナヌザヌが自分に远加するのを埅機したす。単語を远加するメカニズムは耇雑でなく、単玔であり、子䟛でも理解できるものです。

プログラムには、単語を倉曎および削陀する機胜もありたす。 ここでは、すべおが非垞に簡単です。目的のメニュヌ項目をクリックするず、アクティビティが私たちの前に開き、単語がアルファベット順に䞊べられたす。 単語を削陀および倉曎するためのりィンドりは、実際には違いはなく、単語の付いたボタン䞊のアむコンだけなので、1぀のxmlファむルを䜿甚しおそれらを䜜成したした。

画像

画像

ナヌザヌが単語を倉曎するず、単語を远加するためのxmlファむルが䜿甚され、他の機胜でのみ、3぀のフィヌルドすべおに叀い倀が入力されたす。

画像

新しい倀を入力した埌、察応するボタンをクリックするず、サヌバヌ䞊のデヌタベヌスに倉曎を加えるこずなく、単語が倉曎されおナヌザヌのデバむスに保存されたす。 単語や単語の削陀も非垞に簡単です。このプロセスを耇雑にする方法は想像できたせん。

画像

画像

画像からわかるように、すべおの単語を䞀床に削陀するこずも、各単語を個別に削陀するこずもできたすが、削陀する前に確認ダむアログがポップアップ衚瀺されたす。

䞻な機胜の1぀、぀たり単語の远加/削陀/倉曎に぀いお説明したので、最も重芁なものを怜蚎し、これらの単語に埓っおテストに合栌した埌、単語を远加する別の方法を説明したす。

䞊蚘の図では、アルファベット順、逆順、ランダムの3぀の異なる順序でテストに合栌できるこずがわかりたす。 テストオブゞェクトは、英語版、ロシア語、たたは転写のいずれかです。

画像

図からわかるように、単語の英語版のフィヌルドがアクティブになっおいたす。぀たり、このオプションがテストされおいたす。 遞択したテストに応じお、垞に1぀の入力フィヌルドのみがアクティブになり、残りは倉曎されたせん。 「ステヌタス」行は、入力したナヌザヌバヌゞョンが正しいかどうかを瀺したす。確認するには、「確認」ボタンをクリックする必芁がありたす。たた、完了した単語の数ずその数を瀺したす。「次ぞ」ボタンは詳现に怜蚎できたせんが、前の単語に戻るボタンを远加できるこずに泚意しおください。 テストは、最埌の単語たたはメニュヌ項目に到達するこずで完了できたす。

画像

テストに合栌たたは完了したら、結果が泚意を促されたす。

画像

正しく入力された単語は緑色で衚瀺され、残りは赀色で衚瀺されたす。その埌、メむンメニュヌに移動するか、再床テストを受けるこずができたす。

次に、単語を远加する別の方法を怜蚎したす。それを䜿甚するには、[ダりンロヌド]メニュヌ項目に移動する必芁がありたす。ここで、䞊蚘のようにサヌバヌに远加された単語を衚瀺できたす。

画像

図は、このアクティビティは、ボタンの代わりにチェックボックスが存圚するこずを陀いお、実際に倉曎および削陀のアクティブ化ず同じであるこずを瀺しおいたす。

サヌバヌから最埌の単語が返されるたで、ナヌザヌが最埌から2番目の単語に到達した埌、さらに100個がロヌドされるなど、サヌバヌからの単語は小さな郚分、぀たり100個になりたす。 カヌドファむルに単語を远加するには、メニュヌオプションを䜿甚したす。

画像

画像でわかるように、遞択した単語、たたは珟圚ロヌドされおいる単語をダりンロヌドできたす。 保存される単語の数は、メニュヌ項目の巊偎に衚瀺されたす。

䞊の画像では、単語の倉曎/削陀/読み蟌みのアクティブ化に線集-「怜玢」があるこずがわかりたす。 どこでも同じように実装されおいるので、ダりンロヌドりィンドりの䟋のみを怜蚎したす。

実装が簡単であるにもかかわらず、このプログラムでの単語の怜玢は私のお気に入りの開発ですサヌバヌからの単語の読み蟌みをカりントしないでください。 英語ずロシア語の単語を怜玢する「ラむブ」であり、シンプルで䜿いやすいです。

画像

画像

画像

画像

このプログラムには、「View words」ずいうメニュヌ項目もあり、すべおの単語がHTMLテヌブルに衚瀺されたす。

画像

最埌に、すべおのアクティビティのすべおの機胜がメニュヌに耇補されおいたす。

画像

画像

画像

画像

画像

実装


掚枬するこずは難しくなかったので、プログラムは2぀の郚分で構成されたす。これはサヌバヌアプリケヌションずクラむアントアプリケヌションです。したがっお、この項目は2぀の郚分に分割され、それぞれの実装に぀いお個別に説明したす。 特にプログラムの倧郚分は難しくないので、私は最も必芁だず思うものだけを考慮したす。そうしないず、蚘事は非垞に扱いにくくなりたす。

クラむアント郚


クラむアント郚分を順番に説明し始めるので、最初に考慮すべきこずは、メニュヌの䜜成、より正確には、折りたたみ/展開サブメニュヌの実装です。 このフラグメントは非垞に単玔であり、説明はほずんど必芁ないため、コヌドのロゞックのみを説明したす。

<Button android:id="@+id/alphabet" android:layout_width="@dimen/b_size" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/b_alphabet" android:visibility="gone" android:onClick="Alphabet"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <Button android:id="@+id/english1" android:layout_width="@dimen/b_size2" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/b_english" android:visibility="gone" android:onClick="TestingWords"/> <Button android:id="@+id/transcription1" android:layout_width="@dimen/b_size2" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/b_transcription" android:visibility="gone" android:onClick="TestingWords"/> <Button android:id="@+id/russian1" android:layout_width="@dimen/b_size2" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/b_russian" android:visibility="gone" android:onClick="TestingWords"/> </LinearLayout> 

xml-fileコヌドスニペットからわかるように、最初はすべおのサブメニュヌアむテムが非衚瀺になっおいたすが、察応するボタンをクリックするず、それらが衚瀺され、アクティブだった他のアむテムが最小化されたす。機胜の1぀を以䞋に瀺したすが、残りは事実䞊同じです。

 public void Alphabet(View view) { click_alphabet = !click_alphabet; if(Btn_Null()) Btn_Gone(); btn_english = (Button) findViewById(R.id.english1); btn_transcription = (Button) findViewById(R.id.transcription1); btn_russian = (Button) findViewById(R.id.russian1); if(click_alphabet) { btn_english.setVisibility(View.VISIBLE); btn_transcription.setVisibility(View.VISIBLE); btn_russian.setVisibility(View.VISIBLE); btn_alphabet.setText("   -"); } else { Btn_Gone(); btn_alphabet.setText("   +"); } } 

Click_alphabet倉数-ボタンが再床抌されたかどうかを確認し、はいの堎合、この項目が担圓するサブメニュヌが最小化されたす。

関数Btn_Null-すべおのボタンの初期化をチェックしたす。
関数Btn_Gone-すべおのメニュヌ項目/サブ項目を完党に折りたたみたす。

次に、サヌバヌずスマヌトフォンのデヌタベヌスに単語を远加するこずを怜蚎したす。 ナヌザヌが自分に远加したすべおの単語はTreeMap <String、TransRus>クラスに栌玍され、このクラスのキヌは英語の単語であり、トランスクリプションず翻蚳はTransRusクラスに栌玍されたす。

 public class TransRus { private String transcription; private String russian; boolean error; TransRus() { transcription = new String(""); russian = new String(""); error = false; } void getTranscription(String tr) { transcription = tr; } void getRussian(String rs) { russian = rs; } String setTranscription() { return transcription; } String setRussian() { return russian; } void getError(boolean t) { error = t; } boolean setError() { return error; } } 

TreeMapクラスは、CollectionWordsクラスのラッパヌでラップされたす。たた、倧文字ず小文字を無芖するコンパレヌタヌも䜜成されおいたす。

 class ComparatorNotRegister implements Comparator<String> { public int compare(String str1, String str2) { return str1.compareToIgnoreCase(str2); } } public class CollectionWords { static TreeMap<String, TransRus> coll_words = null; static final String file1 = "english"; static final String file2 = "transcription"; static final String file3 = "russian"; static void InitializationCollWords() { if(coll_words != null) return; coll_words = new TreeMap<String, TransRus>(new ComparatorNotRegister()); } static void PutCollWords(String english, String transcription, String russian) { TransRus tr = new TransRus(); tr.getTranscription(transcription); tr.getRussian(russian); coll_words.put(english, tr); } static void ChangedWordEng(String old_english, String new_english, String transcription, String russian) { TransRus temp = coll_words.get(old_english); coll_words.remove(old_english); PutCollWords(new_english, transcription, russian); } static void DeleteWords(String eng) { coll_words.remove(eng); } static void WriteWords(AppCompatActivity t) { try( BufferedWriter eng = new BufferedWriter(new OutputStreamWriter(t.openFileOutput(file1, t.MODE_PRIVATE))); BufferedWriter trans = new BufferedWriter(new OutputStreamWriter(t.openFileOutput(file2, t.MODE_PRIVATE))); BufferedWriter rus = new BufferedWriter(new OutputStreamWriter(t.openFileOutput(file3, t.MODE_PRIVATE)))) { for(Map.Entry<String, TransRus> me : CollectionWords.AllWords()) { eng.write(me.getKey() + "\n"); trans.write(me.getValue().setTranscription() + "\n"); rus.write(me.getValue().setRussian() + "\n"); } } catch (FileNotFoundException e) { Log.d("MyLog", "WF: " + e); } catch (IOException e) { Log.d("MyLog", "WIOE: " + e); } catch(NullPointerException e) { Log.d("MyLog", "WN: " + e); } catch (Exception e) { Log.d("MyLog", "WE: " + e); } } static void ReadWords(AppCompatActivity t) { try( BufferedReader eng = new BufferedReader(new InputStreamReader(t.openFileInput(file1))); BufferedReader trans = new BufferedReader(new InputStreamReader(t.openFileInput(file2))); BufferedReader rus = new BufferedReader(new InputStreamReader(t.openFileInput(file3)))) { String str_eng; String str_trans; String str_rus; while(((str_eng = eng.readLine()) != null) && ((str_trans = trans.readLine()) != null) && ((str_rus = rus.readLine()) != null)) { CollectionWords.PutCollWords(str_eng, str_trans, str_rus); } Log.d("MyLog", "Hyi tam"); } catch (FileNotFoundException e) { Log.d("MyLog", "RF: " + e); } catch (IOException e) { Log.d("MyLog", "RIO: " + e); } catch(NullPointerException e) { Log.d("MyLog", "RN: " + e); } } static Set<Map.Entry<String, TransRus>> AllWords() { return coll_words.entrySet(); } } 

ご芧のずおり、このクラスは難しくありたせん。すべおの単語は英語、転写、ロシア語のテキストファむルに栌玍されおいたす。このため、デヌタベヌスを䜿甚する必芁がありたすが、あたり気にしたせんでした。 すべおがそのように機胜したす。 WriteWords、ReadWords関数は、単語を保存するために䜿甚されたす。関数が機胜するためには、それを呌び出したクラスからthisポむンタヌを枡す必芁があるこずに泚意しおください。 すべおの関数が静的であるずいう事実はすぐに明らかになりたす。これは、クラスを䜕床も耇補しないように特別に行われたものであり、他のすべおは明確であり、コメントは䞍芁です。 远加のシェルに぀いお説明したので、add関数を説明できたす。

 public void AddWord(View view) { CollectionWords.InitializationCollWords(); if(english_language.getText().length() == 0 || russian_language.getText().length() == 0) { Toast toast = Toast.makeText(getApplicationContext(), "  !", Toast.LENGTH_SHORT); toast.show(); return; } if(status != 0 && status == MainActivity.INT_CHG) { CollectionWords.ChangedWordEng(old_english, english_language.getText().toString(), transcription_language.getText().toString().length() == 0 ? "-" : transcription_language.getText().toString(), russian_language.getText().toString()); Back(null); } CollectionWords.PutCollWords(english_language.getText().toString(), (transcription_language.getText().toString().length() == 0 ? "-" : transcription_language.getText().toString()), russian_language.getText().toString()); ClientAddWords caw = new ClientAddWords(); caw.ServerAddWords("1(!!)" + english_language.getText().toString() + "(!!)" + (transcription_language.getText().toString().length() == 0 ? "-" : transcription_language.getText().toString()) + "(!!)" + russian_language.getText().toString()); english_language.setText(""); transcription_language.setText(""); russian_language.setText(""); } 

コヌドスニペットから、ここの必須フィヌルドはenlish_languageずrussian_languageであるこずがわかりたす。これらが入力されおいない堎合、単語は远加されず、関数は終了し、メッセヌゞがポップアップ衚瀺されたす。 前に蚀ったように、単語を远加および倉曎するために、1぀のxml-fileが䜿甚されたす。したがっお、クラスにも2番目のifステヌトメントがあり、この関数ぞの入力が行われたかどうかの倀を栌玍するステヌタス倉数をチェックしたす。蚀葉の倉化。
特に興味深いのは、サヌバヌに単語を送信するために䜿甚されるClientAddWordsクラスです。 なぜなら 珟圚、Android Studioでは、ネットワヌクに関連するすべおが別のスレッドで発生する必芁があるため、これを担圓するクラスを䜜成するこずにしたした。 プログラムには、サヌバヌから単語を返すもう1぀がありたす。

コヌドからわかるように、ClientAddWordsオブゞェクトが最初に䜜成され、次にオブゞェクトが関数を呌び出し、シンボル「!!」で区切られた文字列が枡されたす。このシンボルは、サヌバヌ向けのオペレヌションコヌドこの堎合は「1」ず英語の単語を分離したす、トランスクリプションおよび翻蚳。これは、サヌバヌがデヌタを盞互に正しく分離できるようにするためです。この行はサヌバヌに枡されるず掚枬されるかもしれたせん。

ネットワヌクを操䜜するためのクラスを䜜成するず、ServerAddWords関数が呌び出されたずきにクラむアントがサヌバヌに接続し、転送埌にクラむアントがサヌバヌアプリケヌションから切断されるため、サヌバヌに远加の負荷がかからないため、非垞に䟿利です。 以䞋は、ClientAddWordsクラスです。

 public class ClientAddWords extends Thread { String str_user; void ServerAddWords(String str) { str_user = str; start(); } public void run() { Log.d("MyLog", "Run Client"); InetAddress addr = null; try { addr = InetAddress.getByName("192.168.1.208"); } catch (UnknownHostException e) { Log.d("MyLog", "ServerAddWords ClientAddWords: " + e); } Client c; try { c = new Client(addr); } catch (IOException e) { Log.d("MyLog", "Socket failed: " + e); return; } c.Out(str_user); c.Close(); } } 

ご芧のずおり、このコヌドの実装では、耇雑なこずはなく、远加の説明は䞍芁です。Clientクラスのコヌドを以䞋に瀺したす。

 public class Client extends Thread { private Socket socket; private BufferedReader in; private PrintWriter out; InetAddress addr; public String In() throws IOException { return in.readLine(); } public void Out(String str) { out.println(str); } public Client(InetAddress addr) throws IOException { this.addr = addr; Log.d("MyLog", "Making client"); try { socket = new Socket(addr, 8080); } catch (IOException e) { Log.d("MyLog", "Socket failed: " + e); throw e; } try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); } catch (Exception e) { Log.d("MyLog", "In/Out: " + e); try { socket.close(); } catch (IOException e2) { Log.d("MyLog", "Client: Socket not closed"); } } } public void Close() { try { socket.close(); in.close(); out.close(); } catch (IOException e) { Log.d("MyLog", "Close Client: " + e); } } } 

興味深い点もありたせん。このコヌド䟋は、ネットワヌクプログラミング専甚のWebサむトで芋぀けるこずができたす。

今床は、単語の倉曎ず削陀を行うクラスを芋おいきたす。䜕床も蚀ったように、それらは1぀のxmlファむルを䜿甚し、その実装で最も興味深いのはボタンでレむアりトを埋めるこずです。

 <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_find" > <LinearLayout android:id="@+id/ll_find" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> </LinearLayout> </ScrollView> 

xmlファむル自䜓では、このコヌド郚分のみが察象です。レむアりトがid-ll_findに蚭定されおいるこずがわかりたす。これはプログラムでボタンを䜜成するために必芁です。

 class MyButton extends Button { private String str_eng; private String str_trans; private String str_rus; private int index; public MyButton(Context context) { super(context); } void setEnglish(String eng) { str_eng = eng; } void setTranscription(String trans) { str_trans = trans; } void setRussian(String rus) { str_rus = rus; } void setIndex(int id) { index = id; } String getEnglish() { return str_eng; } String getTranscription() { return str_trans; } String getRussian() { return str_rus; } int getIndex() { return index; } } 

掚枬するのは難しくないので、このクラスはすぐに泚意したす。これは、カヌドの倀、぀たり英語の単語、その転写ず翻蚳を保存するこずのみを目的ずしおいたす

最初に説明する関数はCreateButtonです。コヌドを以䞋に瀺したす。

 public MyButton CreateButton(int i, String eng, String trans, String rus) { final MyButton btnNew = new MyButton(this); btnNew.setBackgroundResource(R.drawable.background_button); btnNew.setText(eng + " - " + rus); btnNew.setEnglish(eng); btnNew.setTranscription(trans); btnNew.setRussian(rus); btnNew.setIndex(i); if(status == MainActivity.INT_DEL) { btnNew.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon_delete_button, 0, 0, 0); btnNew.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AlertDialog.Builder ad; Find context; context = Find.this; String title = " "; String message = " ?"; String button1String = ""; String button2String = ""; ad = new AlertDialog.Builder((Context) context); ad.setTitle(title); ad.setMessage(message); ad.setPositiveButton(button1String, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int arg1) { CollectionWords.DeleteWords(btnNew.getEnglish()); ll_layout.removeView(btnNew); } }); ad.setNegativeButton(button2String, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int arg1) { } }); ad.show(); } }); } else { btnNew.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon_changed_button, 0, 0, 0); btnNew.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("MyLog", "Changed Words"); ChangedWord((MyButton) v); ll_layout.removeView((MyButton) v); } }); } return btnNew; } 

いく぀かの興味深い点がありたす。぀たり、ボタンの背景を倉曎したす。次に、クラスが蚪問する目的に応じお、ボタンのアむコンを䜜成したす。単語ずbtnNewが削陀されるか、ChangedWord関数が呌び出され、単語を倉曎するアクティビティが開きたす。

次に説明する機胜はShowViewWordsで、その目的はボタンをレむアりトに配眮するこずです。

 public void ShowViewWords(LinearLayout.LayoutParams lParams, String sub_str) { int i = 0; String first_chr = new String(""); for(Map.Entry<String, TransRus> me : CollectionWords.AllWords()) { if(sub_str.length() != 0 && (me.getKey().toLowerCase().indexOf(sub_str.toLowerCase()) == -1 && me.getValue().setRussian().toLowerCase().indexOf(sub_str.toLowerCase()) == -1)) continue; if(!first_chr.equals(String.valueOf(me.getKey().toUpperCase().charAt(0)))) { first_chr = String.valueOf(me.getKey().toUpperCase().charAt(0)); TextView temp = new TextView(this); temp.setText(first_chr + ":"); temp.setTextSize(25f); ll_layout.addView(temp, i, lParams); i++; } ll_layout.addView(CreateButton(i, me.getKey(), me.getValue().setTranscription(), me.getValue().setRussian()), i, lParams); i++; } if(i == 0) { LinearLayout.LayoutParams l = CreateParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL); TextView not_found = new TextView(this); not_found.setText("  "); ll_layout.addView(not_found, l); } } 

たた、次の単語の最初の文字ずは異なる、単語の最初の文字の倀を栌玍するTextViewを䜜成しお远加したす。 できる限り説明しようずしたしたが、念のため、䟋ずしお䟋を瀺したす。

画像

このコヌド郚分がこれを担圓したす。

 if(!first_chr.equals(String.valueOf(me.getKey().toUpperCase().charAt(0)))) { first_chr = String.valueOf(me.getKey().toUpperCase().charAt(0)); TextView temp = new TextView(this); temp.setText(first_chr + ":"); temp.setTextSize(25f); ll_layout.addView(temp, i, lParams); i++; } 

最初に、倉数first_chrには空の文字列が割り圓おられたす。そのため、サむクルが初めお通過するず、倀が入力されたす。

この行はルヌプ状態の原因です。

 for(Map.Entry<String, TransRus> me : CollectionWords.AllWords()) 

これは怜玢に関連するため、最初のifステヌトメントの目的に぀いおは埌で説明し、怜玢に぀いおは最埌に説明したす。

  ll_layout.addView(CreateButton(i, me.getKey(), me.getValue().setTranscription(), me.getValue().setRussian()), i, lParams); 

そしお、この構造はll_layoutぞの远加を担圓し、ここでCreateButton関数が呌び出されたす。これは䞊蚘ず芋なされ、MyButton倀を返し、このボタンのむンデックスずパラメヌタヌが远加されたす。

ShowViewWords関数はCreatesButton関数から呌び出され、CreatesButton関数はonCreateから呌び出されたす。 CreatesButtonコヌドは次のずおりです。

 public void CreatesButton(String str_find) { ll_layout.removeAllViews(); LinearLayout.LayoutParams lParams = CreateParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, Gravity.LEFT); lParams.topMargin = 1; ShowViewWords(lParams, str_find); } 

CreateParams関数コヌド

 public LinearLayout.LayoutParams CreateParams(int width, int height, int gravity) { LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(width, height); lParams.gravity = gravity; return lParams; } 

プログラム蚘述のこの段階で、単語のテストを担圓するTestWordsクラスの実装に取り​​組みたした。 い぀ものように、耇雑なこずは䜕もありたせんが、考慮すべき点がいく぀かありたす。 最初の1぀は、ナヌザヌがテストを遞択するこずです。掚枬がどれほど困難であっおも、9぀のテストオプション、぀たり指定された語順アルファベット順、逆順、ランダムおよびテストオブゞェクト英語、転写、ロシア語がありたす。 そのため、StatusTest関数を最初に呌び出したす。 どの線集をブロックするかをコヌドによっお決定し、単語が存圚するむンデックスで倉数を初期化したす。

 public void StatusTest() { switch (status) { case MainActivity.INT_ALPH_ENG: edit_transcription.setRawInputType(0x00000000); edit_russian.setRawInputType(0x00000000); next_words = 0; break; case MainActivity.INT_ALPH_TRANS: edit_english.setRawInputType(0x00000000); edit_russian.setRawInputType(0x00000000); next_words = 0; break; case MainActivity.INT_ALPH_RUS: edit_english.setRawInputType(0x00000000); edit_transcription.setRawInputType(0x00000000); next_words = 0; break; case MainActivity.INT_REVS_ENG: edit_transcription.setRawInputType(0x00000000); edit_russian.setRawInputType(0x00000000); next_words = CollectionWords.coll_words.size() - 1; break; case MainActivity.INT_REVS_TRANS: edit_english.setRawInputType(0x00000000); edit_russian.setRawInputType(0x00000000); next_words = CollectionWords.coll_words.size() - 1; break; case MainActivity.INT_REVS_RUS: edit_english.setRawInputType(0x00000000); edit_transcription.setRawInputType(0x00000000); next_words = CollectionWords.coll_words.size() - 1; break; case MainActivity.INT_RAND_ENG: rand_next_words = new Random(); next_words = MethodRandomWords(); edit_transcription.setRawInputType(0x00000000); edit_russian.setRawInputType(0x00000000); break; case MainActivity.INT_RAND_TRANS: rand_next_words = new Random(); next_words = MethodRandomWords(); edit_english.setRawInputType(0x00000000); edit_russian.setRawInputType(0x00000000); break; case MainActivity.INT_RAND_RUS: rand_next_words = new Random(); next_words = MethodRandomWords(); edit_english.setRawInputType(0x00000000); edit_transcription.setRawInputType(0x00000000); break; } } 

アルファベット順の堎合、next_words倉数には0が割り圓おられたす。逆順は、TreeMapクラスのサむズから1を匕いたものず、next_wordsでランダムな倀を返す特別な関数であるランダムな順序です。

MethodRandomWords関数は、同じランダム倀を数回返さないようにしたす。

すべおの線集を初期化し、StatusTest関数を呌び出した埌、ReadWordメ゜ッドが実行されたす。

 public void ReadWord() { last_words++; amount_words.setText(last_words + "/" + CollectionWords.coll_words.size()); switch (status) { case MainActivity.INT_ALPH_ENG: nw = VecNextWord(next_words); edit_english.setText(""); edit_transcription.setText(nw.getValue().setTranscription()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_ALPH_TRANS: nw = VecNextWord(next_words); edit_transcription.setText(""); edit_english.setText(nw.getKey()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_ALPH_RUS: nw = VecNextWord(next_words); edit_russian.setText(""); edit_english.setText(nw.getKey()); edit_transcription.setText(nw.getValue().setTranscription()); break; case MainActivity.INT_REVS_ENG: nw = VecNextWord(next_words); edit_english.setText(""); edit_transcription.setText(nw.getValue().setTranscription()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_REVS_TRANS: nw = VecNextWord(next_words); edit_transcription.setText(""); edit_english.setText(nw.getKey()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_REVS_RUS: nw = VecNextWord(next_words); edit_russian.setText(""); edit_english.setText(nw.getKey()); edit_transcription.setText(nw.getValue().setTranscription()); break; case MainActivity.INT_RAND_ENG: nw = VecNextWord(next_words); edit_english.setText(""); edit_transcription.setText(nw.getValue().setTranscription()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_RAND_TRANS: nw = VecNextWord(next_words); edit_transcription.setText(""); edit_english.setText(nw.getKey()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_RAND_RUS: nw = VecNextWord(next_words); edit_russian.setText(""); edit_english.setText(nw.getKey()); edit_transcription.setText(nw.getValue().setTranscription()); break; } status_true_word.setText(":-"); } 

このメ゜ッドの目的は、最初のワヌドをロヌドするこずです。VecNextWord関数がこれを担圓したす。そのパラメヌタヌはむンデックスであり、戻り倀はMap.Entry <String、TransRus>です。たた、ワヌド数を瀺し、ステヌタスをリセットしたす。

次の圹割は2぀の機胜のみが果たしたす。チェック-入力された単語の正確性をチェックし、必芁に応じおステヌタス、NextWordを倉曎したす-遞択した順序に応じお、リスト内の次の単語を返したす。 機胜コヌドを以䞋に瀺したす。

 public void Check(View view) { check_bool = true; Log.d("MyLog", "Status: " + status); switch (status) { case MainActivity.INT_ALPH_ENG: Log.d("MyLog", "Check()"); if(edit_english.getText().toString().equals(nw.getKey())) { Log.d("MyLog", "True"); status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { Log.d("MyLog", "False"); status_true_word.setText(":  "); } break; case MainActivity.INT_ALPH_TRANS: Log.d("MyLog", "Check()"); if(edit_transcription.getText().toString().equals(nw.getValue().setTranscription())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_ALPH_RUS: Log.d("MyLog", "Check()"); if(edit_russian.getText().toString().equals(nw.getValue().setRussian())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_REVS_ENG: Log.d("MyLog", "Check()"); if(edit_english.getText().toString().equals(nw.getKey())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_REVS_TRANS: Log.d("MyLog", "Check()"); if(edit_transcription.getText().toString().equals(nw.getValue().setTranscription())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_REVS_RUS: Log.d("MyLog", "Check()"); if(edit_russian.getText().toString().equals(nw.getValue().setRussian())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_RAND_ENG: Log.d("MyLog", "Check()"); if(edit_english.getText().toString().equals(nw.getKey())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_RAND_TRANS: Log.d("MyLog", "Check()"); if(edit_transcription.getText().toString().equals(nw.getValue().setTranscription())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; case MainActivity.INT_RAND_RUS: Log.d("MyLog", "Check()"); if(edit_russian.getText().toString().equals(nw.getValue().setRussian())) { status_true_word.setText(": "); Log.d("MyLog", "next_words: " + next_words); nw.getValue().getError(true); } else { status_true_word.setText(":  "); } break; } } public void NextWord(View view) throws InterruptedException { if(last_words >= CollectionWords.coll_words.size()) { ResultTestGo(); return; } if(!check_bool && last_words != 0) Check(view); AddWordInTable(nw.getValue().setError()); last_words++; amount_words.setText(last_words + "/" + CollectionWords.coll_words.size()); switch (status) { case MainActivity.INT_ALPH_ENG: next_words++; nw = VecNextWord(next_words); edit_english.setText(""); edit_transcription.setText(nw.getValue().setTranscription()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_ALPH_TRANS: next_words++; nw = VecNextWord(next_words); edit_transcription.setText(""); edit_english.setText(nw.getKey()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_ALPH_RUS: next_words++; nw = VecNextWord(next_words); edit_russian.setText(""); edit_english.setText(nw.getKey()); edit_transcription.setText(nw.getValue().setTranscription()); break; case MainActivity.INT_REVS_ENG: next_words--; nw = VecNextWord(next_words); edit_english.setText(""); edit_transcription.setText(nw.getValue().setTranscription()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_REVS_TRANS: next_words--; nw = VecNextWord(next_words); edit_transcription.setText(""); edit_english.setText(nw.getKey()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_REVS_RUS: next_words--; nw = VecNextWord(next_words); edit_russian.setText(""); edit_english.setText(nw.getKey()); edit_transcription.setText(nw.getValue().setTranscription()); break; case MainActivity.INT_RAND_ENG: next_words = MethodRandomWords(); nw = VecNextWord(next_words); edit_english.setText(""); edit_transcription.setText(nw.getValue().setTranscription()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_RAND_TRANS: next_words = MethodRandomWords(); nw = VecNextWord(next_words); edit_transcription.setText(""); edit_english.setText(nw.getKey()); edit_russian.setText(nw.getValue().setRussian()); break; case MainActivity.INT_RAND_RUS: next_words = MethodRandomWords(); nw = VecNextWord(next_words); edit_russian.setText(""); edit_english.setText(nw.getKey()); edit_transcription.setText(nw.getValue().setTranscription()); break; } status_true_word.setText(":-"); check_bool = false; } 

, - , . , , Html-, . , , , AddWordInTable(nw.getValue().setError()), .

 public void AddWordInTable(boolean temp) { table_result += "<tr><td " + (temp ? "bgcolor=\"#008000\"" : "bgcolor=\"#FF0000\"") + ">" + nw.getKey() + "</td><td " + (temp ? "bgcolor=\"#008000\"" : "bgcolor=\"#FF0000\"") + ">" + nw.getValue().setTranscription() + "</td><td " + (temp ? "bgcolor=\"#008000\"" : "bgcolor=\"#FF0000\"") + ">" + nw.getValue().setRussian() + "</td><td " + (temp ? "bgcolor=\"#008000\"" : "bgcolor=\"#FF0000\"") + ">" + (temp ? "" : " ") + "</td></tr>\n"; } 

onCreat, ResultTest, .
, , , ResultTest, , , , Html- loadDataWithBaseURL(null, TestWords.table_result, «text/html», «UTF-8», null), WebView.

, . Load, 18 , .. RecyclerView, - , , . , , Load, .

, , , . xml- CheckBox' TextView', . TextView , . , , , , .

, RecyclerView, , .. , .

, onCreateViewHolder, onBindViewHolder, getItemCount, ViewHolder. GetItemCount , .. . ViewHolder.

 public static class ViewHolder extends RecyclerView.ViewHolder { public CheckBox chkbox; public TextView tv_alph; public ViewHolder(View v) { super(v); chkbox = (CheckBox) v.findViewById(R.id.rv_chkbox); tv_alph = (TextView) v.findViewById(R.id.tv_alph); } } 

. onCreateViewHolder, ViewHolder.

 public RecyclerLoad.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_checkbox, parent, false); ViewHolder vh = new ViewHolder(v); return vh; } 

onBindViewHolder.

 public void onBindViewHolder(final ViewHolder holder, final int position) { if(index_alph[position]) { holder.tv_alph.setText(Alph[position]); holder.tv_alph.setVisibility(View.VISIBLE); } else holder.tv_alph.setVisibility(View.GONE); holder.chkbox.setText(Eng_Array[position] + " - [" + Trans_Array[position] + "] - " + Rus_Array[position]); if(this_load.menu_load_1 != null) this_load.menu_load_1.setTitle("   (" + Integer.toString(amount) + ")"); holder.chkbox.setOnCheckedChangeListener(null); holder.chkbox.setChecked(checked_box[position]); holder.chkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked) checked_words_load++; else checked_words_load--; checked_box[position] = isChecked; if(this_load.menu_load_2 != null) this_load.menu_load_2.setTitle(".   (" + Integer.toString(checked_words_load) + ")"); } }); if (position >= amount - 1) { Log.d("MyLog", "!!!"); LoadWords(sub_str); onBind = true; } } 

, — holder , — CheckBox' setOnCheckedChangeListener setChecked, CheckBox' onCheckedChanged, «» — if , LoadWords.

sub_str, . String, Edit' «: ». なぜなら , Edit'e, .

 find_words.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { FindWord(null); } }); public void FindWord(View view) { mAdapter.Find(find_words.getText().toString()); mAdapter.notifyDataSetChanged(); } 

, FindWord, Find, RecyclerLoad, , , .

 public void Find(String sub_str) { this.sub_str = sub_str; amount = 0; Eng_Array = null; Trans_Array = null; Rus_Array = null; checked_box = null; index_alph = null; Alph = null; LoadWords(sub_str); } 

LoadWords, RecyclerLoad , .. .

 public void LoadWords(String sub_str) { ClientLoadWords clw = new ClientLoadWords(); clw.LoadWords("2(!!)" + (sub_str.length() != 0 ? sub_str : "(--)"), amount); try { clw.join(); } catch (InterruptedException e) { Log.d("MyLog", "ShowViewWords: " + e); } if(clw.int_error == -1) { Toast toast = Toast.makeText(this_load.getApplicationContext(), "   !", Toast.LENGTH_SHORT); toast.show(); } amount += clw.amount; Log.d("MyLog", "amount = " + amount); String [] temp_Eng_Array = new String[amount]; String [] temp_Trans_Array = new String[amount]; String [] temp_Rus_Array = new String[amount]; String [] temp_Alph = new String[amount]; boolean [] temp_checked_box = new boolean[amount]; boolean [] temp_index_alph = new boolean[amount]; int temp_amount = Eng_Array != null ? Eng_Array.length : 0; if(Eng_Array != null) for(int i = 0; i < Eng_Array.length; i++) { temp_Eng_Array[i] = Eng_Array[i]; temp_Trans_Array[i] = Trans_Array[i]; temp_Rus_Array[i] = Rus_Array[i]; temp_Alph[i] = Alph[i]; temp_checked_box[i] = checked_box[i]; temp_index_alph[i] = index_alph[i]; } for(int i = 0; i < clw.amount; i++) { temp_Eng_Array[i + temp_amount] = clw.Eng_Array[i]; temp_Trans_Array[i + temp_amount] = clw.Trans_Array[i]; temp_Rus_Array[i + temp_amount] = clw.Rus_Array[i]; temp_checked_box[i + temp_amount] = false; temp_index_alph[i + temp_amount] = false; temp_Alph[i + temp_amount] = ""; if(!first_chr.equals(String.valueOf(clw.Eng_Array[i].toUpperCase().charAt(0)))) { Log.d("MyLog", "First Chr: " + first_chr + ", me.getKey(): " + clw.Eng_Array[i].toUpperCase().charAt(0) + " boolean: " + first_chr.equals(String.valueOf(clw.Eng_Array[i].toUpperCase().charAt(0)))); first_chr = String.valueOf(clw.Eng_Array[i].toUpperCase().charAt(0)); temp_Alph[i + temp_amount] = first_chr + ":"; temp_index_alph[i + temp_amount] = true; } } for(int i = 0; i < temp_Eng_Array.length; i++) { Log.d("MyLog", "temp_Alph: " + temp_Alph[i] + ", temp_index_alph = " + temp_index_alph[i] + ", i = " + i); } Eng_Array = temp_Eng_Array; Trans_Array = temp_Trans_Array; Rus_Array = temp_Rus_Array; checked_box = temp_checked_box; index_alph = temp_index_alph; Alph = temp_Alph; } 

LoadWords , . - ClientLoadWords — ClientAddWords, , . . LoadWords, , , . LoadWords .

 public void run() { InetAddress addr = null; try { addr = InetAddress.getByName("192.168.1.137"); } catch (UnknownHostException e) { Log.d("MyLog", "ClientLoadWords LoadWords 1: " + e); } Client c; try { c = new Client(addr); } catch (IOException e) { Log.d("MyLog", "Socket failed: " + e); int_error = -1; return; } c.Out(str_user); c.Out(Integer.toString(begin)); amount = 0; try { amount = Integer.parseInt(c.In()); } catch (IOException e) { Log.d("MyLog", "LoadWords ClientLoadWords 3: " + e); } Log.d("MyLog", "Amount: " + amount); Id_Array = new int[amount]; Eng_Array = new String[amount]; Trans_Array = new String[amount]; Rus_Array = new String[amount]; try { for (int i = 0; i < amount; i++) { Id_Array[i] = Integer.parseInt(c.In()); Eng_Array[i] = c.In(); Trans_Array[i] = c.In(); Rus_Array[i] = c.In(); } } catch (IOException e) { Log.d("MyLog", "LoadWords ClientLoadWords 4: " + e); } Sort(); } 

, . , , for, , , .

LoadWords. clw.join() ClientLoadWords, . clw -1, . , , , TextView' index_alph, TextView .

, , .. , , , , . ., , « », , , Html-, , .


, , MySQL TCP, , . / ServerOneJabber. Thread. , .. .

 public ServerOneJabber(Socket s) throws IOException, SQLException { socket = s; in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); sqldb = new SqlDB(); start(); } 

, sqldb, , , . in out In Out, .

 public void run() { String message_user = new String(""); try { message_user = Out(); } catch(IOException e) { System.out.println(e); } System.out.println("message_user: " + message_user); try { switch(message_user.charAt(0)) { case '1': AddWord(message_user); break; case '2': TransferWord(message_user); break; } } catch(SQLException e) { System.out.println(e); } catch(IOException e) { System.out.println(e); } } 

run . .

 public void AddWord(String str) throws SQLException { String[] str_user = Split(str, "(!!)"); for(int i = 0; i < str_user.length; i++) System.out.println("str_user: " + str_user[i]); sqldb.AddWord(str_user[1], str_user[2], str_user[3]); } 

AddWord . sqldb AddWord. Split , , split String , .

 public void TransferWord(String str) throws SQLException, IOException { String [] user_str = Split(str, "(!!)"); for(int i = 0; i < user_str.length; i++) { System.out.println("user_str: " + user_str[i]); } if(sqldb.CountSQL() == 0) { In("0"); return; } int begin = new Integer(Out()); System.out.println("Loading Words..."); String [] data; if(user_str[1].equals("(--)")) data = sqldb.AllWords(); else data = sqldb.Find(user_str[1]); read_amount_words = (data.length - begin > 100 ? 100 : data.length - begin); In(Integer.toString(read_amount_words)); for(int i = begin; i < begin + ((data.length - begin) > 100 ? 100 : data.length); i++) { System.out.println("i = " + i + ", data.length = " + data.length); if(i == data.length) break; String [] str_data = Split(data[i], "(!!)"); for(int j = 0; j < str_data.length; j++) System.out.println("str_data: " + str_data[j]); In(str_data[0]); In(str_data[1]); In(str_data[2]); In(str_data[3]); } } 

TransferWord . , , , , , , . , 100 , 100 , , .

 public class Server { static final int PORT = 8080; static public void main(String[] args) throws IOException { ServerSocket s = new ServerSocket(PORT); System.out.println("Server Started"); try { while(true) { Socket socket = s.accept(); try { System.out.println("Client Connection"); new ServerOneJabber(socket); } catch(IOException e) { socket.close(); } } } catch(SQLException e) { System.out.println(e); } finally { s.close(); } } } 

Server main, , ServerOneJabber .

おわりに


. , , , , - . - , , . .

Source: https://habr.com/ru/post/J303064/


All Articles