1

So basically my goal is to have a ListView filled with large icons which i want to scroll to the previous or next item by clicking a corresponding button. Furthermore I want to highlight (Set the alpha from 30% to 100%) the icon which is currently at top of the screen. Unfortunately some weird things happen when I try to accomplish this. At first, everything works fine. When I click the next button, the list scrolls (by setSelection) to the next element and set the Alpha of the highest element to 100%. But after the third time clicking "next", suddenly not only the highest but also the element below gets an alpha of 100%. From then on all the elements are set to 100% alpha. However if I go up and click the previous button everything works fine also after the third time clicking.

The setting of the highlighted icon happens in the method highlightPreselectedEmoji() in the activity EmojiSelectionActivity. This method is call from within the button listeners prevBtn.setOnClickListener and nextBtn.setOnClickListener. To get the view item which should be highlighted I defined the function getViewByPosition(int pos) in the activity class.

Here the screen how it looks when it works fine: ListView with icons and highlighted first icon

This is how it shouldn't look:

ListView error all icons highlighted

This is the code of the activity:

public class EmojiSelectionActivity extends AppCompatActivity {

private EmojisAdapter emojisAdapter;
private EmojisManager emojisManager;
private ListView emojisContainer;
private Button prevBtn;
private Button nextBtn;
private int currentPosition;
private int previousPosition;
private Activity context  = this;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_emoji_selection);
    Intent intent = getIntent();

    emojisManager = EmojisManager.getInstance(getApplicationContext());
    String detectedEmojiUnicode = intent.getStringExtra("DetectedEmoji");
    emojisManager.setDetectedTags(detectedEmojiUnicode);
    emojisAdapter = new EmojisAdapter(this, emojisManager.getEmojisByTags());

    currentPosition = 0;
    previousPosition = 0;

    initUI();
    loadEmojis();
    highlightPreselectedEmoji();
}

/**
 * Init the UI elements & listeners
 */
private void initUI(){
    prevBtn = (Button) findViewById(R.id.btn_previous_emoji);
    nextBtn = (Button) findViewById(R.id.btn_next_emoji);
    emojisContainer = (ListView) findViewById(R.id.emojisContainer);


    //Set listeners
    emojisContainer.setOnItemClickListener(new AdapterView.OnItemClickListener(){
        public void onItemClick(AdapterView<?> parent, View view, int position, long id){
            Emoji selectedEmoji = emojisAdapter.getItem(position);
            returnToDetectionActivity(selectedEmoji.getUnicodeId());
        }
    });



    prevBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
        public void onClick(View v) {
            if(currentPosition > 0){
                currentPosition --;
                if(currentPosition <= 0){
                    prevBtn.setVisibility(View.INVISIBLE);
                }else{
                    prevBtn.setVisibility(View.VISIBLE);
                }
            }
            nextBtn.setVisibility(View.VISIBLE);
            highlightPreselectedEmoji();
            //getViewByPosition(emojisContainer.getFirstVisiblePosition()).setAlpha(1.0f);

        }
    });

    nextBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
        public void onClick(View v) {
            if(currentPosition < emojisContainer.getAdapter().getCount() - 1 ){
                currentPosition ++;
                if(currentPosition >= emojisContainer.getAdapter().getCount() -1){
                    nextBtn.setVisibility(View.INVISIBLE);
                }else{
                    nextBtn.setVisibility(View.VISIBLE);
                }
            }
            prevBtn.setVisibility(View.VISIBLE);
            highlightPreselectedEmoji();
            //emojisContainer.smoothScrollToPosition(currentPosition);
            //emojisContainer.setSelection(currentPosition);
        }
    });
}

/**
 * Set the currently preselected emoji to an opacity of 100% and the old preselected back to 30% opacity
 */
private void highlightPreselectedEmoji(){
    Log.d("EMOJISELECTION", "*************************scrolling to position: " + currentPosition);
    emojisContainer.setSelection(currentPosition);

    emojisContainer.post(new Runnable() {
        @Override
        public void run() {
            //emojisContainer.smoothScrollToPosition(currentPosition); //Android bug not scrolling properly
            emojisContainer.getFirstVisiblePosition();
            emojisContainer.setItemChecked(currentPosition, true);
            //emojisAdapter.notifyDataSetChanged();
            getViewByPosition(previousPosition).setAlpha(0.3f);
            Log.d("EMOJISELECTION", "set back transparent previous position: " + previousPosition);
            //emojisContainer.findViewById(R.id.img_emoji).setAlpha(0.4f);
            getViewByPosition(currentPosition).setAlpha(1.0f);
            Log.d("EMOJISELECTION", "set highlight current position: " + currentPosition);
            //emojisContainer.getChildAt(currentPosition).setAlpha(1.0f);

            previousPosition = currentPosition;
        }
    });
}

/**
 * Get the view item element of ListView by given position
 * @param pos : position in list
 * @return : view element accroding to the position
 */
private View getViewByPosition(int pos) {
    try {

        final int firstListItemPosition = emojisContainer.getFirstVisiblePosition();
        final int lastListItemPosition = firstListItemPosition + emojisContainer.getChildCount() - 1;

        if (pos < firstListItemPosition || pos > lastListItemPosition ) {
            return emojisAdapter.getView(pos, null, emojisContainer);
        } else {
            final int childIndex = pos - firstListItemPosition;
            return emojisContainer.getChildAt(childIndex);
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

This is the Layout with the ListView:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_gradient">
<com.example.plucinst.emojat.CustomButton
    style="@style/buttonBlackTransparent"
    android:id="@+id/btn_previous_emoji"
    android:layout_marginTop="16dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_alignParentTop="true"
    android:text="@string/button_previous_caption"
    />
<ListView
    android:id="@+id/emojisContainer"
    android:paddingTop="72dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:transcriptMode="alwaysScroll">
</ListView>
<com.example.plucinst.emojat.CustomButton
    android:layout_marginBottom="16dp"
    android:id="@+id/btn_next_emoji"
    style="@style/buttonBlackTransparent"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    android:text="@string/button_next_caption"
    />

</RelativeLayout>

That's the ListView view item:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:alpha="0.3">


<ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"
    android:src="@drawable/clown_face"
    android:id="@+id/img_emoji"/>

This is the BaseAdapter:

public class EmojisAdapter extends BaseAdapter {

private final List<Emoji> emojiList;
private Activity context;
private int emojiDpPaddingSize;
private final float scale;

public EmojisAdapter(Activity context, ArrayList<Emoji> emojiList){
    this.context = context;
    this.emojiList = emojiList;
    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    String paddingSizeString = sharedPrefs.getString("pref_emoji_size", "0");
    switch (paddingSizeString){
        case "0":
            emojiDpPaddingSize = 0;
            break;
        case "32":
            emojiDpPaddingSize = 32;
            break;
        case "64":
            emojiDpPaddingSize = 64;
            break;
        default:
            emojiDpPaddingSize = 0;
            break;
    }
    scale = context.getResources().getDisplayMetrics().density;
}

@Override
public int getCount() {
    if (emojiList != null) {
        return emojiList.size();
    } else {
        return 0;
    }
}

@Override
public Emoji getItem(int position) {
    if (emojiList != null) {
        return emojiList.get(position);
    } else {
        return null;
    }
}



@Override
public long getItemId(int position) {
    return position;
}

public void add(Emoji emoji) {
    emojiList.add(emoji);
}

public void add(List<Emoji> emojis) {
    emojiList.addAll(emojis);
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    EmojisAdapter.ViewHolder holder;
    Emoji emoji = getItem(position);
    String emojiUnicode = emoji.getUnicodeId();

    LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if (convertView == null) {
        convertView = vi.inflate(R.layout.list_item_emoji, null);
        holder = createViewHolder(convertView);
        convertView.setTag(holder);
    } else {
        holder = (EmojisAdapter.ViewHolder) convertView.getTag();
    }
    //holder.viewEmojiIcon.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
    //holder.viewEmojiIcon.setdpTextSize(190);
    //holder.viewEmojiIcon.setIcon(emojiUnicode, true);
    int imgId = context.getResources().getIdentifier(emoji.getImgName(), "drawable", context.getPackageName());
    holder.viewEmojiIcon.setImageResource(imgId);

    int paddingInPixels = (int) (emojiDpPaddingSize *scale + 0.5f);
    int currentPaddingLeftInPixels = (int) (16 *scale + 0.5f);
    int currentPaddingRightInPixels = (int) (16 *scale + 0.5f);
    int paddingTop = holder.viewEmojiIcon.getPaddingTop();
    int paddingBottom = holder.viewEmojiIcon.getPaddingBottom();
    holder.viewEmojiIcon.setPadding(currentPaddingLeftInPixels + paddingInPixels ,paddingTop,currentPaddingRightInPixels + paddingInPixels,paddingBottom);
    //Log.d("EMOJISELECTION", "TextView text" + viewEmojiIcon.getText());

    return convertView;
}


private EmojisAdapter.ViewHolder createViewHolder(View v) {
    EmojisAdapter.ViewHolder holder = new EmojisAdapter.ViewHolder();
    holder.viewEmojiIcon = (ImageView) v.findViewById(R.id.img_emoji);
    return holder;
}

private static class ViewHolder {
    public ImageView viewEmojiIcon;
}

}

tom.a.hawk
  • 53
  • 8
  • The only quick andy dirty solution I found is to just set the alpha also for the view below back to 30% by adding: `getViewByPosition(currentPosition + 1).setAlpha(0.3f) ;` inside the method `highlightPreselectedEmoji()`. Is there a better solution? – tom.a.hawk Apr 01 '17 at 20:53

0 Answers0