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

Android 如何操作ListView的某些元素并手动滚动视图而不发生奇怪的事情?,android,listview,baseadapter,getview,Android,Listview,Baseadapter,Getview,所以基本上我的目标是让ListView充满大图标,我想通过单击相应的按钮滚动到上一个或下一个项目。此外,我想突出显示(将alpha从30%设置为100%)当前位于屏幕顶部的图标。 不幸的是,当我试图实现这一点时,一些奇怪的事情发生了。起初,一切正常。当我单击next按钮时,列表滚动(通过setSelection)到下一个元素,并将最高元素的Alpha设置为100%。但在第三次点击“下一步”后,突然,不仅最高元素,而且下面的元素都得到了100%的alpha值。从那时起,所有元素都设置为100%al

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

高亮显示图标的设置发生在“活动”中的方法
highlightPreselectedEmoji()
中。此方法是从按钮listeners
prevBtn.setOnClickListener
nextBtn.setOnClickListener
中调用的。为了获得应该突出显示的视图项,我在activity类中定义了函数
getViewByPosition(int-pos)

此处显示了工作正常时的屏幕外观:

这是不应该出现的情况:

这是活动的代码:

公共类emojiselection活动扩展了AppCompative活动{

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;
    }
}
私有EmojisAdapter EmojisAdapter;
私人EmojisManager EmojisManager;
私有ListView容器;
专用按钮prevBtn;
私人按钮nextBtn;
私人职位;
私人优先地位;
私人活动上下文=此;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u emoji\u选择);
Intent=getIntent();
emojisManager=emojisManager.getInstance(getApplicationContext());
String detectedemojionicode=intent.getStringExtra(“DetectedEmoji”);
setDetectedTags(detectedEmojiUnicode);
emojisAdapter=新的emojisAdapter(这是emojisManager.getEmojisByTags());
currentPosition=0;
前一位置=0;
initUI();
loadEmojis();
Highlight Preselectedemoji();
}
/**
*初始化UI元素和侦听器
*/
私有void initUI(){
prevBtn=(按钮)findViewById(R.id.btn\u previous\u emoji);
nextBtn=(按钮)findviewbyd(R.id.btn\u next\u emoji);
emojisContainer=(ListView)findViewById(R.id.emojisContainer);
//设置侦听器
emojisContainer.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
Emoji selectedEmoji=emojisAdapter.getItem(位置);
returnToDetectionActivity(selectedEmoji.getUnicodeId());
}
});
prevBtn.setOnClickListener(新建按钮.OnClickListener(){
@凌驾
公共void onClick(视图v){
如果(当前位置>0){
当前位置--;
如果(currentPosition=emojisContainer.getAdapter().getCount()-1){
nextBtn.setVisibility(视图不可见);
}否则{
nextBtn.setVisibility(View.VISIBLE);
}
}
prevBtn.setVisibility(视图可见);
Highlight Preselectedemoji();
//emojisContainer.smoothScrollToPosition(当前位置);
//emojisContainer.setSelection(当前位置);
}
});
}
/**
*将当前预选表情设置为100%不透明度,将旧预选表情设置回30%不透明度
*/
私人虚空高亮预选德莫吉(){
Log.d(“EMOJISELECTION”,“**********************滚动到位置:“+currentPosition”);
emojisContainer.setSelection(当前位置);
emojiscanner.post(新的Runnable(){
@凌驾
公开募捐{
//emojisContainer.smoothScrollToPosition(currentPosition);//Android错误无法正确滚动
emojisContainer.getFirstVisiblePosition();
emojiscanner.setItemChecked(currentPosition,true);
//emojisAdapter.notifyDataSetChanged();
getViewByPosition(先前位置).setAlpha(0.3f);
Log.d(“EMOJISELECTION”,“回退透明的前一位置:“+previousPosition”);
//emojiscanner.findViewById(R.id.img_emoji).setAlpha(0.4f);
getViewByPosition(当前位置).setAlpha(1.0f);
Log.d(“选择”,“设置突出显示当前位置:+currentPosition”);
//emojiscanner.getChildAt(当前位置).setAlpha(1.0f);
previousPosition=当前位置;
}
});
}
/**
*按给定位置获取ListView的视图项元素
*@param pos:列表中的位置
*@return:根据位置查看元素
*/
私有视图getViewByPosition(int pos){
试一试{
final int firstListItemPosition=emojisContainer.getFirstVisiblePosition();
final int lastListItemPosition=firstListItemPosition+emojisContainer.getChildCount()-1;
if(poslastListItemPosition){
返回emojisAdapter.getView(pos,null,emojiscanner);
}否则{
final int childIndex=pos-firstListItemPosition;
返回emojiscanner.getChildAt(childIndex);
}
}捕获(例外e){
e、 printStackTrace();
返回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;
}
公共类EmojisAdapter扩展了BaseAdapter{
私人最终名单;
私人活动语境;
私有int emojiDpPaddingSize;
私人最终浮标