Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Translation activity to spinner #802

Merged
merged 7 commits into from Mar 19, 2017

Conversation

uzairmad
Copy link
Contributor

@uzairmad uzairmad commented Feb 6, 2017

Added link to translations activity from spinner per #760, please review when you have a chance. thanks

@@ -50,6 +50,10 @@
android:title="@string/menu_jump"
app:showAsAction="never" />
<item
android:id="@+id/translations"
android:title="Translations"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use hard-coded string literals, use one provided in strings.xml.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks can fix that, there are items in the home_menu which should be converted as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... there should not be. Android Studio shows them as string literals, but actually they are not.

Overall, you will have to redo this patch anyway. Don't put the menu here. "More translations" option should go to translations spinner in translation screen/mode, the one you see at the top when you have more than one translation are installed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok, i misunderstood that ignore my bottom comment. I can add it in there. jzk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey so ive looked at this a bit, focusing on TranslationsSpinnerAdapter and PagerActivity. I'm running into issues finding a straightforward solution - the translation spinner has a checkbox dropdown item, and implementing another view to the dropdown such as TextView is non-trivial unless both items are added to a parent view. Additionally, since the spinner has checkboxes, an event listener for OnItemSelectedListener isn't being picked up if implemented in PagerActivity. Please let me know if you have some guidance on this. Thank you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose one will have to build a custom adapter that can hold multiple types of items (checkbox and text, in this case).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is where the custom adapter is being made. since SpinnerAdapter is a BaseAdapter, you can just override getViewTypeCount to return 2, and getItemViewType to return 0 except for the last row (the custom row you will add), in which case you'll return 1.

then, in getView, if getItemViewType is 1, show a different xml or just a TextView with "get more translations"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, it appears Spinners don't allow for setting this on the later APIs. "Spinner overrides getViewTypeCount() on the Adapter associated with this view. Calling getItemViewType(int) on the object returned from getAdapter() will always return 0. Calling getViewTypeCount() will always return 1. On API LOLLIPOP and above, attempting to set an adapter with more than one view type will throw an IllegalArgumentException." -https://developer.android.com/reference/android/widget/Spinner.html#setAdapter(android.widget.SpinnerAdapter) also https://code.google.com/p/android/issues/detail?id=17128. It looks like there can be a workaround using Tags however which I can look at

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually have something working, will push later today - overrode getDropDownView as well
translation_item_more

Copy link
Contributor

@ozbek ozbek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will add "Translations" menu, which is not what #760 describes.

Copy link
Contributor

@ahmedre ahmedre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jazakAllah khairan for doing this - some comments

@@ -36,6 +37,9 @@ public TranslationsSpinnerAdapter(Context context,
// and the String[] constructor makes a new (immutable) List with the items of the array.
super(context, resource, new ArrayList<>());
this.layoutInflater = LayoutInflater.from(context);
List<String> transList = new ArrayList<String>(Arrays.asList(translationNames));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List<String> transList = Arrays.asList(translationName);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this, getting java.lang.UnsupportedOperationException on the next line however when trying to add to the list. Is there another way you intended to do this? jzk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, makes sense, because Arrays.asList generates an immutable list.

i'd then replace it with a loop - i.e.

List<String> transList = new ArrayList<>();
for (String translation : translationNames) {
   transList.add(translation);
}

@@ -36,6 +37,9 @@ public TranslationsSpinnerAdapter(Context context,
// and the String[] constructor makes a new (immutable) List with the items of the array.
super(context, resource, new ArrayList<>());
this.layoutInflater = LayoutInflater.from(context);
List<String> transList = new ArrayList<String>(Arrays.asList(translationNames));
transList.add("More Translations");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add to strings.xml and use an R.string value

@@ -36,6 +37,9 @@ public TranslationsSpinnerAdapter(Context context,
// and the String[] constructor makes a new (immutable) List with the items of the array.
super(context, resource, new ArrayList<>());
this.layoutInflater = LayoutInflater.from(context);
List<String> transList = new ArrayList<String>(Arrays.asList(translationNames));
transList.add("More Translations");
translationNames = transList.toArray(new String[transList.size()]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it, you don't need it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this initially as translationNames is also used in addAll(translationNames);, should "More translations" not be a part of the underlying array?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have two options - one is to add it within the underlying array, and the other is to change the adapter to know that "count is always size + 1," and to know that "once you pass this element, the next element is the more option" - if it's cleaner to add it to the array (i.e. if the array is all Strings, as it seems to be), then it probably makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jzk, thanks for the clarification!

@@ -87,24 +91,35 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
CheckBoxHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(
convertView = layoutInflater.inflate(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep wrapped in null check, otherwise, we make a new one every time this is called

@@ -50,6 +50,10 @@
android:title="@string/menu_jump"
app:showAsAction="never" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo changes to this file, not needed.

public void updateItems(String[] translationNames,
List<LocalTranslation> translations,
Set<String> selectedItems) {
clear();
List<String> transList = new ArrayList<String>(Arrays.asList(translationNames));
transList.add("More Translations");
translationNames = transList.toArray(new String[transList.size()]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove, not needed

@@ -204,6 +205,11 @@ public boolean onOptionsItemSelected(MenuItem item) {
jumpToLastPage();
return true;
}
case R.id.translations: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove for now

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {

int type = super.getItemViewType(position);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you can probably remove this method altogether

if (type == 1) {
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(R.layout.translation_ab_spinner_selected, parent, false);
}else{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, spacing

convertView = inflater.inflate(R.layout.translation_ab_spinner_selected, parent, false);
}else{
convertView = super.getView(position, convertView, parent);
SpinnerHolder holder = (SpinnerHolder) convertView.getTag();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure SpinnerHolder lets you get access to the checkbox and then hide/show it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, could you clarify this, I didn't need to change anything here after implementing your other comments. Jzk

Copy link
Contributor

@ozbek ozbek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly cosmetic, but would love to see the changes.

@@ -174,6 +174,7 @@
<string name="prefs_highlight_bookmarks_summary">Highlight bookmarked ayahs while reading</string>
<string name="prefs_translation_text_title">Translation text size</string>
<string name="prefs_translations">Translations</string>
<string name="prefs_more_translations">More Translations</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was basing this off the pattern used for R.string.translations where it referenced <string name="translations">@string/prefs_translations</string>. Otherwise I would've just referenced the string directly. Please let me know if this isn't necessary

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefs_translations is used in the Settings, prefs_more_translations is not used and not needed. Please remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do thanks

}

public String[] updateTranslationNames(String[] translationNames) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jzk, yea this doesn't match the other methods, removing


public String[] updateTranslationNames(String[] translationNames) {

List<String> transList = new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: I don't like the trans prefix. Can you make it translationsList or (since, it is a local variable) simply list would also work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jzk, made into translationsList

holder.checkBox.setText(translationNames[position]);
holder.checkBox.setChecked(selectedItems.contains(translations.get(position).filename));
holder.checkBox.setOnClickListener(onCheckedChangeListener);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

holder.checkBox.setButtonDrawable(transparentDrawable);
holder.checkBox.setText(R.string.more_translations);
holder.checkBox.setOnClickListener(this.textListener);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line.

String desc = QuranInfo.getPageSubtitle(PagerActivity.this, page);
holder.subtitle.setText(desc);
holder.subtitle.setVisibility(View.VISIBLE);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line.

Copy link
Contributor

@ozbek ozbek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JazakAllah khair, looks good to me 👍

@@ -41,6 +41,8 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.LayoutInflater;
import android.widget.TextView;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is not used.


import com.quran.labs.androidquran.R;
import com.quran.labs.androidquran.common.LocalTranslation;

import java.util.ArrayList;
import java.util.Arrays;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import

this.textListener = onClickListener;
}

public String[] updateTranslationNames(String[] translationNames) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make it private

@@ -35,6 +35,7 @@
import com.quran.labs.androidquran.model.bookmark.RecentPageModel;
import com.quran.labs.androidquran.presenter.translation.TranslationManagerPresenter;
import com.quran.labs.androidquran.service.AudioService;
import com.quran.labs.androidquran.ui.TranslationManagerActivity;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import.

@@ -93,18 +99,26 @@ public View getDropDownView(int position, View convertView, ViewGroup parent) {
convertView.setTag(new CheckBoxHolder(convertView));
}
holder = (CheckBoxHolder) convertView.getTag();
if (position == translationNames.length - 1) {
Drawable transparentDrawable = new ColorDrawable(Color.TRANSPARENT);
holder.checkBox.setButtonDrawable(transparentDrawable);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove transparentDrawable and use setButtonDrawable(null) instead.


public String[] updateTranslationNames(String[] translationNames) {
List<String> translationsList = new ArrayList<>();
for (String translation : translationNames) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this for loop and use List<String> translationsList = new ArrayList<>(Arrays.asList(translationNames)); instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jzk, I made the change to a loop based on @ahmedre earlier comment "i'd then replace it with a loop - i.e.

List transList = new ArrayList<>();
for (String translation : translationNames) {
transList.add(translation);
}" , Please let me know if the replacement is what we want as a final state. thanks

@uzairmad
Copy link
Contributor Author

uzairmad commented Mar 1, 2017

waeyyak. Thanks for all the feedback


private String[] updateTranslationNames(String[] translationNames) {
List<String> translationsList = new ArrayList<>();
for (String translation : translationNames) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replaced the for loop with the code from previous comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sure, i had changed it based on Ahmeds comments but i can revert it to this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Let's wait for him on this then. I wonder what's his reasoning for using a for loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sure thing, my only thought would be readability but ill leave the change out for now

@ozbek
Copy link
Contributor

ozbek commented Mar 1, 2017

Oops, this has one major side-effect: note the first translation in the screenshot.

screenshot-2017-03-02-050241

@uzairmad
Copy link
Contributor Author

uzairmad commented Mar 1, 2017

hmm, i didn't see that issue in my test, let me add some more translations and check

@uzairmad
Copy link
Contributor Author

uzairmad commented Mar 1, 2017

I didn't see it in my emulator but am seeing it on my phone, the previous commit from two days ago doesn't have the issue so it must be tied to how the views are being re-used in getDropDownView, checking now. UPDATE: i think this was a result of not setting the checkbox drawable back in the else block within getDropDownView, finding the correct drawable then commiting

holder.checkBox.setText(R.string.more_translations);
holder.checkBox.setOnClickListener(this.textListener);
} else {
holder.checkBox.setButtonDrawable(R.drawable.abc_btn_check_material);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android Studio is complaining that 'The resource @drawable/abc_btn_check_material is marked as private in com.android.support:appcompat'. Can we change its visibility somehow (instead of setting to null or changing its transparency)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, im not sure how this would be done outside of using a drawable, is there a reason other than bloat to bring in the checkbox drawable resource into the project workspace?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's something @ahmedre to decide :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good iA

@ozbek
Copy link
Contributor

ozbek commented Mar 5, 2017

There still seems an issue with API level 14:

android emulator - nexus_one_api_14 5554_002

@ozbek
Copy link
Contributor

ozbek commented Mar 5, 2017

@ahmedre, is #760 really needed? Looking at the changes required, this seems an overkill for a functionality with so little use...

There should be another (better) way of doing this though.

@ahmedre
Copy link
Contributor

ahmedre commented Mar 5, 2017 via email

@ozbek
Copy link
Contributor

ozbek commented Mar 5, 2017

Maybe something like this (remove .zip, apply on top of this PR): pr-802.patch.zip?

(Does GitHub allow changes on other people's PRs, something like Gerrit?)

@ozbek
Copy link
Contributor

ozbek commented Mar 9, 2017

@uzairmad what do you think of the last bug and the patch?

@uzairmad
Copy link
Contributor Author

uzairmad commented Mar 9, 2017

sorry just checked, it looks good for me - I still need to test it on API 14 or if you have already, i can push it in this PR if thats ok. jzk

@uzairmad
Copy link
Contributor Author

uzairmad commented Mar 9, 2017

it looks good on api 14, jzk @ozbek , i can push it
api_14_more_translation

Copy link
Contributor

@ahmedre ahmedre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll approve this, but if you get around to it, try to merge the two view types together.

int type = super.getItemViewType(position);
if (type == 1) {
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(R.layout.translation_ab_spinner_selected, parent, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i still wish we'd share the inflation instead of inflating a separate view

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can do this iA

@ahmedre ahmedre merged commit ac14e36 into quran:master Mar 19, 2017
@ahmedre
Copy link
Contributor

ahmedre commented Mar 19, 2017

jazakAllah khairan

@uzairmad
Copy link
Contributor Author

waiyyakum jazakallahukhairan for the feedback

@uzairmad uzairmad deleted the translation-to-spinner-760 branch March 20, 2017 03:40
ahmedre pushed a commit that referenced this pull request Oct 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants