Satisfy most warnings
.idea/misc.xml
| 1 | 1 | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | 2 | <project version="4"> | |
| 3 | - | <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | |
| 3 | + | <component name="DesignSurface"> | |
| 4 | + | <option name="filePathToZoomLevelMap"> | |
| 5 | + | <map> | |
| 6 | + | <entry key="../../../../../../layout/custom_preview.xml" value="0.23385416666666667" /> | |
| 7 | + | </map> | |
| 8 | + | </option> | |
| 9 | + | </component> | |
| 10 | + | <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> | |
| 4 | 11 | <output url="file://$PROJECT_DIR$/build/classes" /> | |
| 5 | 12 | </component> | |
| 6 | 13 | <component name="ProjectType"> |
app/src/main/java/eu/lepiller/nani/AboutActivity.java
| 18 | 18 | Button report_button = findViewById(R.id.report_button); | |
| 19 | 19 | Button mozc_button = findViewById(R.id.mozc_button); | |
| 20 | 20 | ||
| 21 | - | sources_button.setOnClickListener(new View.OnClickListener() { | |
| 22 | - | @Override | |
| 23 | - | public void onClick(View v) { | |
| 24 | - | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://framagit.org/nani-project/nani-app")); | |
| 25 | - | startActivity(browserIntent); | |
| 26 | - | } | |
| 21 | + | sources_button.setOnClickListener(v -> { | |
| 22 | + | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://framagit.org/nani-project/nani-app")); | |
| 23 | + | startActivity(browserIntent); | |
| 27 | 24 | }); | |
| 28 | 25 | ||
| 29 | - | report_button.setOnClickListener(new View.OnClickListener() { | |
| 30 | - | @Override | |
| 31 | - | public void onClick(View v) { | |
| 32 | - | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://framagit.org/nani-project/nani-app/issues")); | |
| 33 | - | startActivity(browserIntent); | |
| 34 | - | } | |
| 26 | + | report_button.setOnClickListener(v -> { | |
| 27 | + | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://framagit.org/nani-project/nani-app/issues")); | |
| 28 | + | startActivity(browserIntent); | |
| 35 | 29 | }); | |
| 36 | 30 | ||
| 37 | - | mozc_button.setOnClickListener(new View.OnClickListener() { | |
| 38 | - | @Override | |
| 39 | - | public void onClick(View v) { | |
| 40 | - | String appPackageName = "org.mozc.android.inputmethod.japanese"; | |
| 41 | - | try { | |
| 42 | - | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName))); | |
| 43 | - | } catch (android.content.ActivityNotFoundException e) { | |
| 44 | - | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName))); | |
| 45 | - | } | |
| 31 | + | mozc_button.setOnClickListener(v -> { | |
| 32 | + | String appPackageName = "org.mozc.android.inputmethod.japanese"; | |
| 33 | + | try { | |
| 34 | + | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName))); | |
| 35 | + | } catch (android.content.ActivityNotFoundException e) { | |
| 36 | + | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName))); | |
| 46 | 37 | } | |
| 47 | 38 | }); | |
| 48 | 39 | } |
app/src/main/java/eu/lepiller/nani/DictionaryActivity.java
| 1 | 1 | package eu.lepiller.nani; | |
| 2 | 2 | ||
| 3 | + | import android.app.Activity; | |
| 3 | 4 | import android.content.Intent; | |
| 4 | 5 | import android.os.AsyncTask; | |
| 5 | 6 | import android.os.Bundle; | |
| 7 | + | ||
| 8 | + | import androidx.activity.result.contract.ActivityResultContracts; | |
| 6 | 9 | import androidx.appcompat.app.AppCompatActivity; | |
| 7 | 10 | import androidx.lifecycle.LiveData; | |
| 8 | 11 | import androidx.lifecycle.MutableLiveData; | |
| 9 | - | import androidx.lifecycle.Observer; | |
| 10 | 12 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; | |
| 11 | 13 | ||
| 12 | 14 | import android.util.Log; | |
… | |||
| 61 | 63 | adapter = new DictionariesAdapter(this, dictionaries); | |
| 62 | 64 | list_view.setAdapter(adapter); | |
| 63 | 65 | ||
| 64 | - | langAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, langs); | |
| 66 | + | langAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, langs); | |
| 65 | 67 | langAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); | |
| 66 | 68 | lang_view.setAdapter(langAdapter); | |
| 67 | 69 | ||
… | |||
| 71 | 73 | refresh(); | |
| 72 | 74 | } | |
| 73 | 75 | ||
| 74 | - | list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |
| 75 | - | @Override | |
| 76 | - | public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | |
| 77 | - | Intent intent = new Intent(DictionaryActivity.this, DictionaryDownloadActivity.class); | |
| 78 | - | intent.putExtra(DictionaryDownloadActivity.EXTRA_DICTIONARY, DictionaryFactory.get(position).getName()); | |
| 79 | - | startActivityForResult(intent, DICO_REQUEST); | |
| 80 | - | } | |
| 76 | + | list_view.setOnItemClickListener((parent, view, position, id) -> { | |
| 77 | + | Intent intent = new Intent(DictionaryActivity.this, DictionaryDownloadActivity.class); | |
| 78 | + | intent.putExtra(DictionaryDownloadActivity.EXTRA_DICTIONARY, DictionaryFactory.get(position).getName()); | |
| 79 | + | ||
| 80 | + | registerForActivityResult( | |
| 81 | + | new ActivityResultContracts.StartActivityForResult(), | |
| 82 | + | result -> { | |
| 83 | + | if (result.getResultCode() == Activity.RESULT_OK) { | |
| 84 | + | updateDataSet(); | |
| 85 | + | } | |
| 86 | + | }).launch(intent); | |
| 81 | 87 | }); | |
| 82 | 88 | ||
| 83 | 89 | lang_view.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | |
… | |||
| 102 | 108 | protected void onResume() { | |
| 103 | 109 | super.onResume(); | |
| 104 | 110 | setObserver(); | |
| 105 | - | refresher.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { | |
| 106 | - | @Override | |
| 107 | - | public void onRefresh() { | |
| 108 | - | refresh(); | |
| 109 | - | } | |
| 110 | - | }); | |
| 111 | + | refresher.setOnRefreshListener(this::refresh); | |
| 111 | 112 | updateDataSet(); | |
| 112 | 113 | } | |
| 113 | 114 | ||
… | |||
| 123 | 124 | ||
| 124 | 125 | private void setObserver() { | |
| 125 | 126 | LiveData<Boolean> data = DownloadTask.getRefreshingData(); | |
| 126 | - | data.observe(this, new Observer<Boolean>() { | |
| 127 | - | @Override | |
| 128 | - | public void onChanged(Boolean refreshing) { | |
| 129 | - | refresher.setRefreshing(refreshing); | |
| 130 | - | if(!refreshing) | |
| 131 | - | updateDataSet(); | |
| 132 | - | } | |
| 127 | + | data.observe(this, refreshing -> { | |
| 128 | + | refresher.setRefreshing(refreshing); | |
| 129 | + | if(!refreshing) | |
| 130 | + | updateDataSet(); | |
| 133 | 131 | }); | |
| 134 | 132 | } | |
| 135 | 133 | ||
… | |||
| 199 | 197 | adapter.notifyDataSetChanged(); | |
| 200 | 198 | langAdapter.notifyDataSetChanged(); | |
| 201 | 199 | } | |
| 202 | - | ||
| 203 | - | @Override | |
| 204 | - | protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
| 205 | - | super.onActivityResult(requestCode, resultCode, data); | |
| 206 | - | if (requestCode == DICO_REQUEST) { | |
| 207 | - | updateDataSet(); | |
| 208 | - | } | |
| 209 | - | } | |
| 210 | - | ||
| 211 | 200 | } | |
app/src/main/java/eu/lepiller/nani/DictionaryDownloadActivity.java
| 5 | 5 | import android.os.Build; | |
| 6 | 6 | ||
| 7 | 7 | import androidx.appcompat.app.AppCompatActivity; | |
| 8 | + | import androidx.core.content.res.ResourcesCompat; | |
| 8 | 9 | import androidx.lifecycle.LiveData; | |
| 9 | 10 | import androidx.lifecycle.Observer; | |
| 10 | 11 | ||
… | |||
| 80 | 81 | if (dictionaryName == null) | |
| 81 | 82 | return; | |
| 82 | 83 | ||
| 83 | - | observer = new Observer<DictionaryDownloadService.DownloadData>() { | |
| 84 | - | @Override | |
| 85 | - | public void onChanged(DictionaryDownloadService.DownloadData downloadData) { | |
| 86 | - | boolean pending = false; | |
| 87 | - | for(String n: downloadData.downloading) { | |
| 88 | - | if(n.equals(dictionaryName)) { | |
| 89 | - | pending = true; | |
| 90 | - | break; | |
| 91 | - | } | |
| 84 | + | observer = downloadData -> { | |
| 85 | + | boolean pending = false; | |
| 86 | + | for(String n: downloadData.downloading) { | |
| 87 | + | if(n.equals(dictionaryName)) { | |
| 88 | + | pending = true; | |
| 89 | + | break; | |
| 92 | 90 | } | |
| 93 | - | Log.d(TAG, "onChanged: " + downloadData.currentName); | |
| 94 | - | ||
| 95 | - | if(dictionaryName.equals(downloadData.currentName)) { | |
| 96 | - | download_bar.setMax(100); | |
| 97 | - | if(downloadData.currentProgress >= 0) { | |
| 98 | - | download_bar.setIndeterminate(false); | |
| 99 | - | download_bar.setProgress(downloadData.currentProgress); | |
| 100 | - | } else { | |
| 101 | - | download_bar.setIndeterminate(true); | |
| 102 | - | } | |
| 103 | - | updateLayout(true); | |
| 104 | - | } else if(pending) { | |
| 91 | + | } | |
| 92 | + | Log.d(TAG, "onChanged: " + downloadData.currentName); | |
| 93 | + | ||
| 94 | + | if(dictionaryName.equals(downloadData.currentName)) { | |
| 95 | + | download_bar.setMax(100); | |
| 96 | + | if(downloadData.currentProgress >= 0) { | |
| 97 | + | download_bar.setIndeterminate(false); | |
| 98 | + | download_bar.setProgress(downloadData.currentProgress); | |
| 99 | + | } else { | |
| 105 | 100 | download_bar.setIndeterminate(true); | |
| 106 | - | updateLayout(true); | |
| 101 | + | } | |
| 102 | + | updateLayout(true); | |
| 103 | + | } else if(pending) { | |
| 104 | + | download_bar.setIndeterminate(true); | |
| 105 | + | updateLayout(true); | |
| 106 | + | } else { | |
| 107 | + | if(d.isDownloaded()) { | |
| 108 | + | download_bar.setProgress(100); | |
| 107 | 109 | } else { | |
| 108 | - | if(d.isDownloaded()) { | |
| 109 | - | download_bar.setProgress(100); | |
| 110 | - | } else { | |
| 111 | - | download_bar.setProgress(d.getSize()*100 / d.getExpectedFileSize()); | |
| 112 | - | } | |
| 113 | - | updateLayout(false); | |
| 110 | + | download_bar.setProgress(d.getSize()*100 / d.getExpectedFileSize()); | |
| 114 | 111 | } | |
| 112 | + | updateLayout(false); | |
| 115 | 113 | } | |
| 116 | 114 | }; | |
| 117 | 115 | data.observe(this, observer); | |
… | |||
| 175 | 173 | else | |
| 176 | 174 | size_view.setText(String.format(getResources().getString(R.string.dictionary_size_mb), size/1000000)); | |
| 177 | 175 | ||
| 178 | - | trash_button.setOnClickListener(new View.OnClickListener() { | |
| 179 | - | @Override | |
| 180 | - | public void onClick(View v) { | |
| 181 | - | d.remove(); | |
| 182 | - | updateLayout(isDownloading); | |
| 183 | - | } | |
| 176 | + | trash_button.setOnClickListener(v -> { | |
| 177 | + | d.remove(); | |
| 178 | + | updateLayout(isDownloading); | |
| 184 | 179 | }); | |
| 185 | 180 | } | |
| 186 | 181 | ||
| 187 | 182 | private void setIcon(ImageView download_button, int drawableResId) { | |
| 188 | - | Drawable drawable; | |
| 189 | - | if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { | |
| 190 | - | drawable = getResources().getDrawable(drawableResId, getTheme()); | |
| 191 | - | } else { | |
| 192 | - | drawable = getResources().getDrawable(drawableResId); | |
| 193 | - | } | |
| 183 | + | Drawable drawable = ResourcesCompat.getDrawable(getResources(), drawableResId, getTheme()); | |
| 194 | 184 | download_button.setImageDrawable(drawable); | |
| 195 | 185 | } | |
| 196 | 186 | } | |
app/src/main/java/eu/lepiller/nani/DictionaryDownloadService.java
| 66 | 66 | .setContentText(getString(R.string.downloading)) | |
| 67 | 67 | .setOnlyAlertOnce(true); | |
| 68 | 68 | downloadQueue = new DownloadQueue(); | |
| 69 | - | Downloader downloadThread = new Downloader(new Runnable() { | |
| 70 | - | @Override | |
| 71 | - | public void run() { | |
| 72 | - | stopForeground(true); | |
| 73 | - | stopSelf(); | |
| 74 | - | } | |
| 69 | + | Downloader downloadThread = new Downloader(() -> { | |
| 70 | + | stopForeground(true); | |
| 71 | + | stopSelf(); | |
| 75 | 72 | }); | |
| 76 | 73 | new Thread(downloadThread).start(); | |
| 77 | 74 | } | |
… | |||
| 122 | 119 | final DownloadData downloadData = new DownloadData(name, progress, downloadQueue.downloadQueue()); | |
| 123 | 120 | ||
| 124 | 121 | Handler threadHandler = new Handler(Looper.getMainLooper()); | |
| 125 | - | threadHandler.post(new Runnable() { | |
| 126 | - | @Override | |
| 127 | - | public void run() { | |
| 128 | - | if(data == null) | |
| 129 | - | data = new MutableLiveData<>(); | |
| 130 | - | data.setValue(downloadData); | |
| 131 | - | } | |
| 122 | + | threadHandler.post(() -> { | |
| 123 | + | if(data == null) | |
| 124 | + | data = new MutableLiveData<>(); | |
| 125 | + | data.setValue(downloadData); | |
| 132 | 126 | }); | |
| 133 | 127 | } | |
| 134 | 128 | ||
| 135 | 129 | private static class DownloadQueue { | |
| 136 | - | private ArrayList<String> downloadQueue = new ArrayList<>(); | |
| 130 | + | private final ArrayList<String> downloadQueue = new ArrayList<>(); | |
| 137 | 131 | private boolean waitsForFirstWork = true; | |
| 138 | 132 | private boolean stopAsked = false; | |
| 139 | - | private ReentrantLock mutex = new ReentrantLock(); | |
| 133 | + | private final ReentrantLock mutex = new ReentrantLock(); | |
| 140 | 134 | ||
| 141 | 135 | ArrayList<String> downloadQueue() { | |
| 142 | 136 | try { | |
… | |||
| 221 | 215 | } | |
| 222 | 216 | ||
| 223 | 217 | private class Downloader implements Runnable { | |
| 224 | - | private Runnable onStop; | |
| 218 | + | private final Runnable onStop; | |
| 225 | 219 | ||
| 226 | 220 | Downloader(Runnable onStop) { | |
| 227 | 221 | this.onStop = onStop; | |
app/src/main/java/eu/lepiller/nani/HelpActivity.java
| 24 | 24 | } | |
| 25 | 25 | ||
| 26 | 26 | private<T> View.OnClickListener getOpenListener(final Class<T> c) { | |
| 27 | - | return new View.OnClickListener() { | |
| 28 | - | @Override | |
| 29 | - | public void onClick(View v) { | |
| 30 | - | Intent intent = new Intent(HelpActivity.this, c); | |
| 31 | - | startActivity(intent); | |
| 32 | - | } | |
| 27 | + | return v -> { | |
| 28 | + | Intent intent = new Intent(HelpActivity.this, c); | |
| 29 | + | startActivity(intent); | |
| 33 | 30 | }; | |
| 34 | 31 | } | |
| 35 | 32 | } |
app/src/main/java/eu/lepiller/nani/HelpPitchActivity.java
| 16 | 16 | setContentView(R.layout.activity_help_pitch); | |
| 17 | 17 | ||
| 18 | 18 | Button wikiButton = findViewById(R.id.wiki_button); | |
| 19 | - | wikiButton.setOnClickListener(new View.OnClickListener() { | |
| 20 | - | @Override | |
| 21 | - | public void onClick(View v) { | |
| 22 | - | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help_pitch_wiki_link))); | |
| 23 | - | startActivity(browserIntent); | |
| 24 | - | } | |
| 19 | + | wikiButton.setOnClickListener(v -> { | |
| 20 | + | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help_pitch_wiki_link))); | |
| 21 | + | startActivity(browserIntent); | |
| 25 | 22 | }); | |
| 26 | 23 | } | |
| 27 | 24 | } | |
| 27 | 24 | = | |
| 28 | 25 | = | \ No newline at end of file |
app/src/main/java/eu/lepiller/nani/MainActivity.java
| 1 | 1 | package eu.lepiller.nani; | |
| 2 | 2 | ||
| 3 | + | import android.annotation.SuppressLint; | |
| 3 | 4 | import android.content.Intent; | |
| 4 | 5 | import android.content.SharedPreferences; | |
| 5 | 6 | import android.os.AsyncTask; | |
… | |||
| 51 | 52 | ||
| 52 | 53 | static final String TAG = "MAIN"; | |
| 53 | 54 | ||
| 55 | + | // At this point we really need to redraw pagerAdapter, so suppress the warning. | |
| 56 | + | @SuppressLint("NotifyDataSetChanged") | |
| 54 | 57 | @Override | |
| 55 | 58 | protected void onCreate(Bundle savedInstanceState) { | |
| 56 | 59 | super.onCreate(savedInstanceState); | |
… | |||
| 83 | 86 | tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_kanji)); | |
| 84 | 87 | ||
| 85 | 88 | new TabLayoutMediator(tabLayout, viewPager2, | |
| 86 | - | new TabLayoutMediator.TabConfigurationStrategy() { | |
| 87 | - | @Override | |
| 88 | - | public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { | |
| 89 | - | tab.setText(position == 0? R.string.tab_results: R.string.tab_kanji); | |
| 90 | - | } | |
| 91 | - | } | |
| 89 | + | (tab, position) -> tab.setText(position == 0? R.string.tab_results: R.string.tab_kanji) | |
| 92 | 90 | ).attach(); | |
| 93 | 91 | ||
| 94 | 92 | try { | |
… | |||
| 98 | 96 | e.printStackTrace(); | |
| 99 | 97 | } | |
| 100 | 98 | ||
| 101 | - | radical_button.setOnClickListener(new View.OnClickListener() { | |
| 102 | - | @Override | |
| 103 | - | public void onClick(View v) { | |
| 104 | - | try { | |
| 105 | - | DictionaryFactory.getRadicalDictionary(getApplicationContext()); | |
| 106 | - | radical_selector.setVisibility(View.VISIBLE); | |
| 107 | - | result_layout.setVisibility(View.INVISIBLE); | |
| 108 | - | search_form.setIconified(false); | |
| 109 | - | } catch (NoDictionaryException e) { | |
| 110 | - | Snackbar.make(search_form, getString(R.string.no_radical_dict), Snackbar.LENGTH_LONG).show(); | |
| 111 | - | } | |
| 99 | + | radical_button.setOnClickListener(v -> { | |
| 100 | + | try { | |
| 101 | + | DictionaryFactory.getRadicalDictionary(getApplicationContext()); | |
| 102 | + | radical_selector.setVisibility(View.VISIBLE); | |
| 103 | + | result_layout.setVisibility(View.INVISIBLE); | |
| 104 | + | search_form.setIconified(false); | |
| 105 | + | } catch (NoDictionaryException e) { | |
| 106 | + | Snackbar.make(search_form, getString(R.string.no_radical_dict), Snackbar.LENGTH_LONG).show(); | |
| 112 | 107 | } | |
| 113 | 108 | }); | |
| 114 | 109 | ||
| 115 | - | radical_selector.setOnCloseEventListener(new View.OnClickListener() { | |
| 116 | - | @Override | |
| 117 | - | public void onClick(View v) { | |
| 118 | - | closeRadicals(); | |
| 119 | - | } | |
| 120 | - | }); | |
| 110 | + | radical_selector.setOnCloseEventListener(v -> closeRadicals()); | |
| 121 | 111 | ||
| 122 | - | radical_selector.setOnClickEventListener(new View.OnClickListener() { | |
| 123 | - | @Override | |
| 124 | - | public void onClick(View v) { | |
| 125 | - | String k = ((Button)v).getText().toString(); | |
| 126 | - | search_form.setQuery(search_form.getQuery() + k, false); | |
| 127 | - | } | |
| 112 | + | radical_selector.setOnClickEventListener(v -> { | |
| 113 | + | String k = ((Button)v).getText().toString(); | |
| 114 | + | search_form.setQuery(search_form.getQuery() + k, false); | |
| 128 | 115 | }); | |
| 129 | 116 | ||
| 130 | - | radical_selector.setOnHelpEventListener(new View.OnClickListener() { | |
| 131 | - | @Override | |
| 132 | - | public void onClick(View v) { | |
| 133 | - | Intent intent = new Intent(MainActivity.this, HelpRadicalActivity.class); | |
| 134 | - | startActivity(intent); | |
| 135 | - | } | |
| 117 | + | radical_selector.setOnHelpEventListener(v -> { | |
| 118 | + | Intent intent = new Intent(MainActivity.this, HelpRadicalActivity.class); | |
| 119 | + | startActivity(intent); | |
| 136 | 120 | }); | |
| 137 | 121 | ||
| 138 | 122 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { | |
… | |||
| 155 | 139 | } else if(key.compareTo(SettingsActivity.KEY_PREF_READING_STYLE) == 0) { | |
| 156 | 140 | readingStyle = getReadingSizePref(sharedPreferences); | |
| 157 | 141 | pagerAdapter.setReadingStyle(readingStyle); | |
| 158 | - | pagerAdapter.notifyDataSetChanged(); | |
| 142 | + | pagerAdapter.notifyItemChanged(0); | |
| 159 | 143 | } | |
| 160 | 144 | } | |
| 161 | 145 | ||
| 162 | 146 | private int getRadSizePref(SharedPreferences sharedPrefs) { | |
| 163 | 147 | String prefRadSize = sharedPrefs.getString(SettingsActivity.KEY_PREF_RAD_SIZE, "122"); | |
| 164 | - | if(prefRadSize == null) | |
| 165 | - | prefRadSize = "122"; | |
| 166 | 148 | return Integer.parseInt(prefRadSize); | |
| 167 | 149 | } | |
| 168 | 150 | ||
| 169 | 151 | private String getReadingSizePref(SharedPreferences sharedPreferences) { | |
| 170 | - | String prefReadingStyle = sharedPreferences.getString(SettingsActivity.KEY_PREF_READING_STYLE, "furigana"); | |
| 171 | - | if(prefReadingStyle == null) | |
| 172 | - | prefReadingStyle = "furigana"; | |
| 173 | - | return prefReadingStyle; | |
| 152 | + | return sharedPreferences.getString(SettingsActivity.KEY_PREF_READING_STYLE, "furigana"); | |
| 174 | 153 | } | |
| 175 | 154 | ||
| 176 | 155 | private static class SearchTask extends AsyncTask<String, Integer, SearchResult> { | |
… | |||
| 279 | 258 | } | |
| 280 | 259 | sb.append(s); | |
| 281 | 260 | } | |
| 282 | - | feedback_text.setText(String.format(getString(R.string.feedback_no_result_tried), sb.toString())); | |
| 261 | + | feedback_text.setText(String.format(getString(R.string.feedback_no_result_tried), sb)); | |
| 283 | 262 | } | |
| 284 | 263 | return; | |
| 285 | 264 | } | |
… | |||
| 297 | 276 | final String moji = converter.convertRomajiToHiragana(r.getText()); | |
| 298 | 277 | feedback_text.setText(String.format(getString(R.string.feedback_didyoumean), moji)); | |
| 299 | 278 | ||
| 300 | - | feedback_text.setOnClickListener(new View.OnClickListener() { | |
| 301 | - | @Override | |
| 302 | - | public void onClick(View v) { | |
| 303 | - | search_form.setQuery(moji, true); | |
| 304 | - | feedback_text.setOnClickListener(null); | |
| 305 | - | } | |
| 279 | + | feedback_text.setOnClickListener(v -> { | |
| 280 | + | search_form.setQuery(moji, true); | |
| 281 | + | feedback_text.setOnClickListener(null); | |
| 306 | 282 | }); | |
| 307 | 283 | } | |
| 308 | 284 | ||
… | |||
| 314 | 290 | ||
| 315 | 291 | pagerAdapter.setKanjiResults(kanjiResults); | |
| 316 | 292 | pagerAdapter.setResults(searchResult); | |
| 317 | - | pagerAdapter.notifyDataSetChanged(); | |
| 293 | + | pagerAdapter.notifyItemChanged(0); | |
| 294 | + | pagerAdapter.notifyItemChanged(1); | |
| 318 | 295 | } | |
| 319 | 296 | ||
| 320 | 297 | @Override | |
… | |||
| 327 | 304 | ||
| 328 | 305 | search_form.setQueryHint(getResources().getString(R.string.search_hint)); | |
| 329 | 306 | ||
| 330 | - | search_form.setOnCloseListener(new SearchView.OnCloseListener() { | |
| 331 | - | @Override | |
| 332 | - | public boolean onClose() { | |
| 333 | - | closeRadicals(); | |
| 334 | - | return false; | |
| 335 | - | } | |
| 307 | + | search_form.setOnCloseListener(() -> { | |
| 308 | + | closeRadicals(); | |
| 309 | + | return false; | |
| 336 | 310 | }); | |
| 337 | 311 | ||
| 338 | 312 | search_form.setOnQueryTextListener(new SearchView.OnQueryTextListener() { | |
… | |||
| 347 | 321 | return false; | |
| 348 | 322 | } | |
| 349 | 323 | ||
| 350 | - | pagerAdapter.setKanjiResults(new ArrayList<KanjiResult>()); | |
| 351 | - | pagerAdapter.setResults(new ArrayList<Result>()); | |
| 352 | - | pagerAdapter.notifyDataSetChanged(); | |
| 353 | - | ||
| 324 | + | pagerAdapter.setKanjiResults(new ArrayList<>()); | |
| 325 | + | pagerAdapter.setResults(new ArrayList<>()); | |
| 326 | + | pagerAdapter.notifyItemChanged(0); | |
| 327 | + | pagerAdapter.notifyItemChanged(1); | |
| 354 | 328 | search_form.setEnabled(false); | |
| 355 | 329 | feedback_text.setText(R.string.feedback_progress); | |
| 356 | 330 | ||
app/src/main/java/eu/lepiller/nani/PitchDiagramView.java
| 16 | 16 | import java.util.ArrayList; | |
| 17 | 17 | ||
| 18 | 18 | public class PitchDiagramView extends View { | |
| 19 | - | private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 19 | + | private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 20 | 20 | private int textColor = Color.BLACK; | |
| 21 | 21 | private int pitchColor = Color.BLACK; | |
| 22 | 22 | private ArrayList<Pair<String, Boolean>> pitchedMora = new ArrayList<>(); | |
… | |||
| 25 | 25 | ||
| 26 | 26 | private float textSize = 32; | |
| 27 | 27 | ||
| 28 | - | private static final String TAG = "PITCHVIEW"; | |
| 29 | - | ||
| 30 | 28 | public PitchDiagramView(Context context) { | |
| 31 | 29 | super(context); | |
| 32 | 30 | setDefaults(); | |
app/src/main/java/eu/lepiller/nani/RadicalSelectorView.java
| 110 | 110 | radicalButton.setTextSize(getRadFontSize()); | |
| 111 | 111 | radicalButton.setLayoutParams(new FlexboxLayout.LayoutParams(radSize, radSize)); | |
| 112 | 112 | ||
| 113 | - | radicalButton.setOnClickListener(new OnClickListener() { | |
| 114 | - | @Override | |
| 115 | - | public void onClick(View v) { | |
| 116 | - | boolean checked = ((ToggleButton) v).isChecked(); | |
| 117 | - | if (checked) { | |
| 118 | - | selected.add(radical); | |
| 119 | - | } else { | |
| 120 | - | selected.remove(radical); | |
| 121 | - | } | |
| 122 | - | ||
| 123 | - | String[] set = new String[selected.size()]; | |
| 124 | - | for(int i=0; i<selected.size(); i++) { | |
| 125 | - | set[i] = selected.get(i); | |
| 126 | - | } | |
| 127 | - | new DictionarySearchTask(RadicalSelectorView.this, dictionary).execute(set); | |
| 113 | + | radicalButton.setOnClickListener(v -> { | |
| 114 | + | boolean checked = ((ToggleButton) v).isChecked(); | |
| 115 | + | if (checked) { | |
| 116 | + | selected.add(radical); | |
| 117 | + | } else { | |
| 118 | + | selected.remove(radical); | |
| 128 | 119 | } | |
| 120 | + | ||
| 121 | + | String[] set = new String[selected.size()]; | |
| 122 | + | for(int i=0; i<selected.size(); i++) { | |
| 123 | + | set[i] = selected.get(i); | |
| 124 | + | } | |
| 125 | + | new DictionarySearchTask(RadicalSelectorView.this, dictionary).execute(set); | |
| 129 | 126 | }); | |
| 130 | 127 | box.addView(radicalButton); | |
| 131 | 128 | } |
app/src/main/java/eu/lepiller/nani/ResultPagerAdapter.java
| 1 | 1 | package eu.lepiller.nani; | |
| 2 | 2 | ||
| 3 | + | import android.annotation.SuppressLint; | |
| 3 | 4 | import android.content.Context; | |
| 4 | 5 | import android.content.Intent; | |
| 5 | 6 | import android.text.Html; | |
… | |||
| 26 | 27 | static List<Result> results = new ArrayList<>(); | |
| 27 | 28 | static List<KanjiResult> kanjiResults = new ArrayList<>(); | |
| 28 | 29 | private static String readingStyle = "furigana"; | |
| 29 | - | private Context context; | |
| 30 | + | private final Context context; | |
| 30 | 31 | ||
| 31 | 32 | static final String TAG = "RESULTS_PAGER"; | |
| 32 | 33 | ||
| 33 | 34 | public static class ViewHolder extends RecyclerView.ViewHolder { | |
| 34 | - | private LinearLayout result_view; | |
| 35 | - | private Context context; | |
| 35 | + | private final LinearLayout result_view; | |
| 36 | + | private final Context context; | |
| 36 | 37 | ||
| 37 | 38 | ViewHolder(View view, Context context) { | |
| 38 | 39 | super(view); | |
… | |||
| 98 | 99 | ||
| 99 | 100 | StringBuilder sb = new StringBuilder(); | |
| 100 | 101 | boolean separator1 = false; | |
| 101 | - | for (String s : meanings.get(lang)) { | |
| 102 | - | if (separator1) | |
| 103 | - | sb.append(context.getResources().getString(R.string.sense_separator)); | |
| 104 | - | else | |
| 105 | - | separator1 = true; | |
| 106 | - | sb.append(s); | |
| 102 | + | List<String> langs = meanings.get(lang); | |
| 103 | + | if(langs != null) { | |
| 104 | + | for (String s : langs) { | |
| 105 | + | if (separator1) | |
| 106 | + | sb.append(context.getResources().getString(R.string.sense_separator)); | |
| 107 | + | else | |
| 108 | + | separator1 = true; | |
| 109 | + | sb.append(s); | |
| 110 | + | } | |
| 107 | 111 | } | |
| 108 | 112 | sense_view.setText(Html.fromHtml(sb.toString())); | |
| 109 | 113 | ||
… | |||
| 149 | 153 | if(pitch != null) { | |
| 150 | 154 | pitch_view.setVisibility(View.VISIBLE); | |
| 151 | 155 | pitch_view.setText(pitch); | |
| 152 | - | pitch_view.setOnClickListener(new View.OnClickListener() { | |
| 153 | - | @Override | |
| 154 | - | public void onClick(View v) { | |
| 155 | - | Intent intent = new Intent(context, HelpPitchActivity.class); | |
| 156 | - | context.startActivity(intent); | |
| 157 | - | } | |
| 156 | + | pitch_view.setOnClickListener(v -> { | |
| 157 | + | Intent intent = new Intent(context, HelpPitchActivity.class); | |
| 158 | + | context.startActivity(intent); | |
| 158 | 159 | }); | |
| 159 | 160 | } | |
| 160 | 161 | ||
… | |||
| 193 | 194 | } | |
| 194 | 195 | } | |
| 195 | 196 | ||
| 196 | - | private LayoutInflater mInflater; | |
| 197 | + | private final LayoutInflater mInflater; | |
| 197 | 198 | ResultPagerAdapter(Context context) { | |
| 198 | 199 | this.mInflater = LayoutInflater.from(context); | |
| 199 | 200 | this.context = context; | |
… | |||
| 219 | 220 | return 2; | |
| 220 | 221 | } | |
| 221 | 222 | ||
| 223 | + | // Changing the style requires redrawing everything, so suppress warning | |
| 224 | + | @SuppressLint("NotifyDataSetChanged") | |
| 222 | 225 | public void setReadingStyle(String readingStyle) { | |
| 223 | 226 | ResultPagerAdapter.readingStyle = readingStyle; | |
| 224 | 227 | Log.d(TAG, "reading style updated to " + readingStyle); | |
| 225 | 228 | notifyDataSetChanged(); | |
| 226 | 229 | } | |
| 227 | 230 | ||
| 231 | + | @SuppressLint("NotifyDataSetChanged") | |
| 228 | 232 | public void setKanjiResults(List<KanjiResult> kanjiResults) { | |
| 229 | 233 | if(kanjiResults == null) | |
| 230 | 234 | return; | |
… | |||
| 235 | 239 | notifyDataSetChanged(); | |
| 236 | 240 | } | |
| 237 | 241 | ||
| 242 | + | @SuppressLint("NotifyDataSetChanged") | |
| 238 | 243 | public void setResults(List<Result> results) { | |
| 239 | 244 | if(results == null) | |
| 240 | 245 | return; | |
app/src/main/java/eu/lepiller/nani/dictionary/DictionariesAdapter.java
| 18 | 18 | import eu.lepiller.nani.R; | |
| 19 | 19 | ||
| 20 | 20 | public class DictionariesAdapter extends ArrayAdapter<Dictionary> { | |
| 21 | - | private Context context; | |
| 21 | + | private final Context context; | |
| 22 | 22 | ||
| 23 | 23 | public DictionariesAdapter(Context context, ArrayList<Dictionary> dictionaries) { | |
| 24 | 24 | super(context, 0, dictionaries); |
app/src/main/java/eu/lepiller/nani/dictionary/Dictionary.java
| 5 | 5 | import android.graphics.Canvas; | |
| 6 | 6 | import android.graphics.drawable.BitmapDrawable; | |
| 7 | 7 | import android.graphics.drawable.Drawable; | |
| 8 | - | import android.os.Build; | |
| 9 | 8 | import android.util.Pair; | |
| 10 | 9 | ||
| 10 | + | import androidx.core.content.res.ResourcesCompat; | |
| 11 | + | ||
| 11 | 12 | import java.io.File; | |
| 12 | 13 | import java.io.FileInputStream; | |
| 13 | 14 | import java.io.FileNotFoundException; | |
… | |||
| 21 | 22 | import eu.lepiller.nani.R; | |
| 22 | 23 | ||
| 23 | 24 | abstract public class Dictionary { | |
| 24 | - | private String name; | |
| 25 | - | private String description, fullDescription, lang; | |
| 26 | - | private int expectedFileSize; | |
| 27 | - | private int expectedEntries; | |
| 28 | - | private String sha256; | |
| 29 | - | private File file, temporaryFile; | |
| 25 | + | private final String name; | |
| 26 | + | private final String description, fullDescription, lang; | |
| 27 | + | private final int expectedFileSize; | |
| 28 | + | private final int expectedEntries; | |
| 29 | + | private final String sha256; | |
| 30 | + | private final File file, temporaryFile; | |
| 30 | 31 | ||
| 31 | - | private Drawable drawable=null, newDrawable=null; | |
| 32 | + | private Drawable drawable, newDrawable; | |
| 32 | 33 | ||
| 33 | 34 | Dictionary(String name, String description, String fullDescription, File cacheDir, int fileSize, int entries, String hash, String lang) { | |
| 34 | 35 | this.name = name; | |
… | |||
| 84 | 85 | public Drawable getDrawable(Context context) { | |
| 85 | 86 | if(drawable == null) { | |
| 86 | 87 | int drawableResId = getDrawableId(); | |
| 87 | - | if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { | |
| 88 | - | drawable = context.getResources().getDrawable(drawableResId, context.getTheme()); | |
| 89 | - | } else { | |
| 90 | - | drawable = context.getResources().getDrawable(drawableResId); | |
| 91 | - | } | |
| 88 | + | drawable = ResourcesCompat.getDrawable(context.getResources(), drawableResId, context.getTheme()); | |
| 92 | 89 | } | |
| 93 | 90 | return drawable; | |
| 94 | 91 | } | |
… | |||
| 115 | 112 | // Ensure we have the base icon | |
| 116 | 113 | getDrawable(context); | |
| 117 | 114 | ||
| 118 | - | Drawable star; | |
| 119 | - | if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { | |
| 120 | - | star = context.getResources().getDrawable(R.drawable.ic_star, context.getTheme()); | |
| 121 | - | } else { | |
| 122 | - | star = context.getResources().getDrawable(R.drawable.ic_star); | |
| 123 | - | } | |
| 115 | + | Drawable star = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_star, context.getTheme()); | |
| 124 | 116 | ||
| 125 | 117 | canvas.drawBitmap(drawableToBitmap(drawable, 640, 640), 0, 0, null); | |
| 126 | 118 | canvas.drawBitmap(drawableToBitmap(star, 220, 220), 390, 390, null); | |
app/src/main/java/eu/lepiller/nani/dictionary/FileDictionary.java
| 36 | 36 | void skipVals(RandomAccessFile file, long pos) throws IOException; | |
| 37 | 37 | } | |
| 38 | 38 | ||
| 39 | - | private String mUrl; | |
| 39 | + | private final String mUrl; | |
| 40 | 40 | private final static String TAG = "FileDictionary"; | |
| 41 | 41 | ||
| 42 | 42 | FileDictionary(String name, String description, String fullDescription, File cacheDir, String url, |
app/src/main/java/eu/lepiller/nani/dictionary/IncompatibleFormatException.java
| 1 | 1 | package eu.lepiller.nani.dictionary; | |
| 2 | 2 | ||
| 3 | 3 | public class IncompatibleFormatException extends DictionaryException { | |
| 4 | - | private String name; | |
| 4 | + | private final String name; | |
| 5 | 5 | ||
| 6 | 6 | IncompatibleFormatException(String name) { | |
| 7 | 7 | this.name = name; |
app/src/main/java/eu/lepiller/nani/dictionary/NoResultDictionaryException.java
| 4 | 4 | import java.util.List; | |
| 5 | 5 | ||
| 6 | 6 | public class NoResultDictionaryException extends DictionaryException { | |
| 7 | - | private ArrayList<String> tried; | |
| 7 | + | private final ArrayList<String> tried; | |
| 8 | 8 | ||
| 9 | 9 | public NoResultDictionaryException(ArrayList<String> tried) { | |
| 10 | 10 | this.tried = tried; |
app/src/main/java/eu/lepiller/nani/dictionary/ResultDictionary.java
| 164 | 164 | readingHuffman = loadHuffman(file); | |
| 165 | 165 | meaningHuffman = loadHuffman(file); | |
| 166 | 166 | ||
| 167 | - | logHuffman(readingHuffman, new ArrayList<Boolean>()); | |
| 167 | + | logHuffman(readingHuffman, new ArrayList<>()); | |
| 168 | 168 | ||
| 169 | 169 | // Search in Japanese, by kanji and reading | |
| 170 | 170 | Log.d(TAG, "search: by kanji and reading"); |
app/src/main/java/eu/lepiller/nani/dictionary/WadokuPitchDictionary.java
| 63 | 63 | file.readInt(); | |
| 64 | 64 | ||
| 65 | 65 | huffman = loadHuffman(file); | |
| 66 | - | logHuffman(huffman, new ArrayList<Boolean>()); | |
| 66 | + | logHuffman(huffman, new ArrayList<>()); | |
| 67 | 67 | ||
| 68 | 68 | triePos = file.getFilePointer(); | |
| 69 | 69 | } |
app/src/main/java/eu/lepiller/nani/result/KanjiResult.java
| 5 | 5 | ||
| 6 | 6 | public class KanjiResult { | |
| 7 | 7 | public static class Sense { | |
| 8 | - | private String lang, content; | |
| 8 | + | private final String lang, content; | |
| 9 | 9 | public Sense(String lang, String content) { | |
| 10 | 10 | this.lang = lang; | |
| 11 | 11 | this.content = content; | |
… | |||
| 19 | 19 | return lang; | |
| 20 | 20 | } | |
| 21 | 21 | } | |
| 22 | - | private String kanji; | |
| 23 | - | private int stroke; | |
| 24 | - | private List<Sense> senses; | |
| 22 | + | private final String kanji; | |
| 23 | + | private final int stroke; | |
| 24 | + | private final List<Sense> senses; | |
| 25 | 25 | private List<String> on; | |
| 26 | - | private List<String> kun; | |
| 27 | - | private List<String> nanori; | |
| 26 | + | private final List<String> kun; | |
| 27 | + | private final List<String> nanori; | |
| 28 | 28 | ||
| 29 | 29 | public KanjiResult(String kanji, int stroke, List<Sense> senses, List<String> kun, List<String> on, List<String> nanori) { | |
| 30 | 30 | this.kanji = kanji; | |
app/src/main/java/eu/lepiller/nani/result/Result.java
| 14 | 14 | ||
| 15 | 15 | public class Result { | |
| 16 | 16 | public static class Source { | |
| 17 | - | private ArrayList<String> content; | |
| 18 | - | private boolean wasei; | |
| 19 | - | private String language; | |
| 17 | + | private final ArrayList<String> content; | |
| 18 | + | private final boolean wasei; | |
| 19 | + | private final String language; | |
| 20 | 20 | ||
| 21 | 21 | public Source(ArrayList<String> content, boolean wasei, String language) { | |
| 22 | 22 | this.content = content; | |
… | |||
| 26 | 26 | } | |
| 27 | 27 | ||
| 28 | 28 | public static class Sense { | |
| 29 | - | private ArrayList<String> references, limits, infos, glosses; | |
| 30 | - | private String language; | |
| 31 | - | private ArrayList<Source> sources; | |
| 29 | + | private final ArrayList<String> references, limits, infos, glosses; | |
| 30 | + | private final String language; | |
| 31 | + | private final ArrayList<Source> sources; | |
| 32 | 32 | ||
| 33 | 33 | public Sense(ArrayList<String> references, ArrayList<String> limits, ArrayList<String> infos, | |
| 34 | 34 | ArrayList<Source> sources, ArrayList<String> glosses, | |
… | |||
| 55 | 55 | } | |
| 56 | 56 | ||
| 57 | 57 | public static class Reading { | |
| 58 | - | private ArrayList<String> kanjis, infos, readings, pitches; | |
| 58 | + | private final ArrayList<String> kanjis, infos, readings, pitches; | |
| 59 | 59 | ||
| 60 | 60 | public Reading(ArrayList<String> kanjis, ArrayList<String> infos, ArrayList<String> readings) { | |
| 61 | 61 | this.kanjis = kanjis; | |
… | |||
| 77 | 77 | } | |
| 78 | 78 | } | |
| 79 | 79 | ||
| 80 | - | private ArrayList<String> kanjis; | |
| 81 | - | private ArrayList<Reading> readings; | |
| 82 | - | private ArrayList<Sense> senses; | |
| 83 | - | private int score; | |
| 80 | + | private final ArrayList<String> kanjis; | |
| 81 | + | private final ArrayList<Reading> readings; | |
| 82 | + | private final ArrayList<Sense> senses; | |
| 83 | + | private final int score; | |
| 84 | 84 | ||
| 85 | 85 | public Result(ArrayList<String> kanjis, ArrayList<Reading> readings, ArrayList<Sense> senses, int score) { | |
| 86 | 86 | this.kanjis = kanjis; | |
… | |||
| 176 | 176 | if(Character.UnicodeBlock.of(c) == KATAKANA) { | |
| 177 | 177 | current.append("["); | |
| 178 | 178 | current.append(c); | |
| 179 | - | current.append(converter.convertRomajiToHiragana(converter.convertKanaToRomaji(new String(new char[]{c})))); | |
| 179 | + | current.append(converter.convertRomajiToHiragana(converter.convertKanaToRomaji(String.valueOf(c)))); | |
| 180 | 180 | current.append("]"); | |
| 181 | 181 | } else { | |
| 182 | 182 | current.append(c); | |
… | |||
| 186 | 186 | } | |
| 187 | 187 | current.append("$"); | |
| 188 | 188 | ||
| 189 | - | Log.v("RESULT", "regex: " + current.toString()); | |
| 189 | + | Log.v("RESULT", "regex: " + current); | |
| 190 | 190 | ||
| 191 | 191 | Pattern p = Pattern.compile(current.toString()); | |
| 192 | 192 | Matcher m = p.matcher(reading); | |
… | |||
| 214 | 214 | current.append(" "); | |
| 215 | 215 | } | |
| 216 | 216 | } | |
| 217 | - | Log.v("RESULT", "Finaly: " + current.toString()); | |
| 217 | + | Log.v("RESULT", "Finaly: " + current); | |
| 218 | 218 | return current.toString(); | |
| 219 | 219 | } | |
| 220 | 220 | ||