自动滚动到 Adapter 中的某个位置

Automatically scroll to a position in an Adapter

我试图让我的程序自动滚动到由全局整数 AtlasApplication.sSelectedPositionForLaw 设置的整数位置。我曾尝试在 SubMenuActivity 中使用 mNotificationLv.smoothScrollToPostion(AtlasApplication.sSelectedPositionForLaw) 但没有成功。如何让 SubMenuActivity 自动滚动到适配器中的选定位置?

子菜单活动

@Override
protected void onResume() {
    try {
        super.onResume();
        FontLoader.loadFonts(this);
        headerLayout.LoadHeaderFont();
        footerLayout.LoadFooterFont();
        FontLoader.setRalewayBoldFont(mSubMenuHeaderTv);
        FontLoader.setAwesomeFont(mSubMenuBackTv);
        FontLoader.setAtlasFont(mSubMenuIconTv);
        loadSubMenuLabel();
        subMenuAdapter.setList(AtlasApplication.lstLawsForLocation);
        mNotificationLv.setAdapter(subMenuAdapter);
        mNotificationLv.smoothScrollToPosition(21);

        activityResumed();
    }
    catch(Exception e){
        exceptionHandler.handle(e, "onResume()");
    }
} 

子菜单适配器

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.row_sub_menu_item, null);
        holder = new ViewHolder();
        holder.rowSubMenuLl = (LinearLayout) convertView.findViewById(R.id.row_sub_menu_ll);
        holder.mSubMenuTitleTv = (TextView) convertView.findViewById(R.id.sub_menu_title_tv);
        holder.mSubMenuDetailPane = (LinearLayout) convertView.findViewById(R.id.sub_menu_detail_pane_ll);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    FontLoader.setRalewayRegularFont(holder.mSubMenuTitleTv);

    LawModel notificationModel = lstSubMenuModels.get(position);

    if(Integer.parseInt(notificationModel.getTagID()) == AtlasApplication.sSelectedPositionForLaw) {
        notificationModel.setSelected(true);
    }

    holder.mSubMenuTitleTv.setText(notificationModel.getTagName().trim());

    if (notificationModel.isSelected) {
        //AtlasApplication.SubMenuTitle = notificationModel.getTagName();
        AtlasApplication.sLawModelSelected = notificationModel;
        AtlasApplication.sSelectedPositionForLaw=position;
        if (holder.mSubMenuDetailPane.getChildCount() < 1) {
            SpeedingFines sf = new SpeedingFines(context, holder.mSubMenuDetailPane);
            sf.setPriorityListener(mOnPriorityUpdateListener);

            holder.rowSubMenuLl.setBackgroundResource(R.color.taxes_bg);
            holder.mSubMenuDetailPane.requestFocus();
        }
    } else {
        holder.mSubMenuDetailPane.removeAllViews();
        holder.rowSubMenuLl.setBackgroundResource(R.color.grad_dark);
    }

    holder.mSubMenuTitleTv.setId(position);
    holder.mSubMenuTitleTv.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            setAllselectedFalse(v.getId());
            lstSubMenuModels.get(v.getId()).isSelected = !lstSubMenuModels.get(v.getId()).isSelected;
            notifyDataSetChanged();
        }
    });
    return convertView;
}

private void setAllselectedFalse(int selectedRow) {
    AtlasApplication.sSelectedPositionForLaw=-1;
    for (int i = 0; i < lstSubMenuModels.size(); i++) {
        if (i != selectedRow) {
            lstSubMenuModels.get(i).setSelected(false);
        }
    }
}

public void setList(List<LawModel> subMenuModels) {
    this.lstSubMenuModels = subMenuModels;
    notifyDataSetChanged();
}

private class ViewHolder {
    TextView mSubMenuTitleTv;
    LinearLayout rowSubMenuLl, mSubMenuDetailPane;
}

我来解决你的问题:

计算到达正确位置的观看次数,几乎可以到达您的位置:

int sum = 0;
for (int i = 0; i < mListView.getChildCount(); i++) {
    if(sum > position){
        mListView.smoothScrollToPosition(i);
        break;
    }
    sum = sum + mListView.getChildAt(i).getHeight();
}

祝你好运...

以前我做过类似的事情,我可以通过这种方式滚动到自定义位置:

    listView.post(new Runnable() {
        @Override
        public void run() {
            listView.smoothScrollToPosition(position);
        }
    });

因此,在您的情况下可以是:

@Override
protected void onResume() {
try {
    super.onResume();
    FontLoader.loadFonts(this);
    headerLayout.LoadHeaderFont();
    footerLayout.LoadFooterFont();
    FontLoader.setRalewayBoldFont(mSubMenuHeaderTv);
    FontLoader.setAwesomeFont(mSubMenuBackTv);
    FontLoader.setAtlasFont(mSubMenuIconTv);
    loadSubMenuLabel();
    subMenuAdapter.setList(AtlasApplication.lstLawsForLocation);
    mNotificationLv.setAdapter(subMenuAdapter);
    mNotificationLv.post(new Runnable() {
        @Override
        public void run() {
            mNotificationLv.smoothScrollToPosition(21);
        }
    });

    activityResumed();
}
catch(Exception e){
    exceptionHandler.handle(e, "onResume()");
}

}

我认为的原因是

the UI(user interface) of android work based on a queue of things to do, and making in a runnable post function you are telling the UI, when it can, after it has done all things in queue perform some actions, in this case to scroll to certain position of listView.