如何操作ListView的某些元素并手动滚动视图而不会发生奇怪的事情?

时间:2017-03-31 09:51:05

标签: android listview baseadapter getview

所以基本上我的目标是让ListView填充大图标,我想通过单击相应的按钮滚动到上一个或下一个项目。此外,我想突出显示(将alpha从30%设置为100%)当前位于屏幕顶部的图标。 不幸的是,当我试图完成这个时,会发生一些奇怪的事情。一开始,一切正常。当我单击下一个按钮时,列表会滚动(通过setSelection)到下一个元素,并将最高元素的Alpha设置为100%。但是在第三次点击" next"之后,突然不仅最高,而且下面的元素得到100%的alpha。从那时起,所有元素都设置为100%alpha。但是,如果我上去点击上一个按钮,第三次点击后一切正常。

突出显示图标的设置发生在活动highlightPreselectedEmoji()中的方法EmojiSelectionActivity中。此方法是从按钮侦听器prevBtn.setOnClickListenernextBtn.setOnClickListener内调用的。要获取应突出显示的视图项,我在活动类中定义了函数getViewByPosition(int pos)

此处屏幕显示工作正常时的外观: ListView with icons and highlighted first icon

这是它不应该看的样子:

ListView error all icons highlighted

这是活动的代码:

公共类EmojiSelectionActivity扩展了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;
    }
}

这是使用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>

这是ListView视图项:

<?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"/>

这是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;
}

}

0 个答案:

没有答案