android - 获取屏幕上的位置以便在 View 持有者中查看

标签 android android-recyclerview android-viewholder

我有一个由适配器管理的 Recyclerview。对于回收器中的每个项目,我都会膨胀一个复杂的 View ,其中还包含一个占据整个屏幕宽度的水平进度条。

我必须放置一个带有百分比值(20%、60% 等)的气球 TextView,该值指向进度条,就像进度量的指示器一样。我尝试使用此代码

int[] startPosition =  new int[2];
Integer progresswidth;
WindowManager wm = (WindowManager) contextthis.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
progresswidth = size.x;
holder.horiz_progress.getLocationOnScreen(startPosition);
float exactvalue = (progresswidth * currentitem.getMatchPercent()) / 100;
startPosition[0] = startPosition[0] + Math.round(exactvalue);
startPosition[0] = startPosition[0] - holder.baloon_txt.getWidth() / 3 ;
startPosition[1] = startPosition[1] + 10;
holder.baloon_txt.setX(startPosition[0]);
holder.baloon_txt.setY(startPosition[1]);

但问题是 holder.horiz_progress.getLocationOnScreen 始终返回 0,因此我无法定位 balloon_txt。 我在 Activity 中遇到了类似的问题,我通过覆盖 OnWindowFocusChanged 解决了它,但这是在适配器内部,所以我不知道如何完成它。

编辑

我当前的适配器代码:

public class ResultsAdapter extends RecyclerView.Adapter<ResultsAdapter.ViewHolder>{

private List<ResultsItem> mResults;
private View mSelectedView;
private int mSelectedPosition;
Context contextthis;
android.os.Handler handler;
int[] startPosition =  new int[2];

public ResultsAdapter(Context context,List<ResultsItem> resultsItemList) {
    this.mResults = resultsItemList;
    contextthis = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.results_item, null);
    final ViewHolder viewHolder = new ViewHolder(v);

    viewHolder.results_likeimg.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        }
    });

    return viewHolder;
}

@Override
public void onBindViewHolder( final ViewHolder holder, int position) {
    final ResultsItem currentitem = mResults.get(position);
    //set Image
    if(currentitem.getImageslist().get(0).getPicture() != null)
        ImageLoader.getInstance().displayImage(currentitem.getImageslist().get(0).getPicture(), holder.results_img);

    //baloon set
    holder.baloon_txt.setText(currentitem.getMatchPercent() + "% " + "Match");
    holder.horiz_progress.setProgress(currentitem.getMatchPercent());
    final View view = holder.horiz_progress;
            view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            view.getLocationOnScreen(startPosition);
            Integer progresswidth;
            WindowManager wm = (WindowManager) contextthis.getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            progresswidth = size.x;
            float exactvalue = (progresswidth * currentitem.getMatchPercent()) / 100;
            startPosition[0] = startPosition[0] + Math.round(exactvalue);
            startPosition[0] = startPosition[0] - holder.baloon_txt.getWidth() / 3 ;
            startPosition[1] = startPosition[1] + 10;
            holder.baloon_txt.setX(startPosition[0]);
            holder.baloon_txt.setY(startPosition[1]);
        }
    });


    //logo
    if(currentitem.getPriceslist().get(0).getSource() != null)
        ImageLoader.getInstance().displayImage(currentitem.getPriceslist().get(0).getSource(), holder.results_logo_img);

    //description
    holder.description_txt.setText(currentitem.getDescription());

    //price
    holder.price_curr.setText(currentitem.getPriceslist().get(0).getCurrency());
    holder.price_txt.setText(String.valueOf(currentitem.getPriceslist().get(0).getPrice()));
}

@Override
public int getItemCount() {
    return mResults.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    ImageView results_img, results_dislikeimg, results_likeimg, results_logo_img;
    ProgressBar horiz_progress;
    TextView baloon_txt, price_txt, description_txt, buybtn, sharebtn, price_curr;

    public ViewHolder(View view) {
        super(view);

        this.results_img = (ImageView) view.findViewById(R.id.resultsitem_img);
        this.results_dislikeimg = (ImageView) view.findViewById(R.id.results_item_dislike);
        this.results_likeimg = (ImageView) view.findViewById(R.id.resultsitem_like);
        this.results_logo_img = (ImageView) view.findViewById(R.id.logoimg);
        this.horiz_progress = (ProgressBar) view.findViewById(R.id.progressBar_horizontal);
        this.baloon_txt = (TextView) view.findViewById(R.id.baloonMatch_txt);
        this.price_txt = (TextView) view.findViewById(R.id.price_txt);
        this.description_txt = (TextView) view.findViewById(R.id.description_txt);
        this.buybtn = (TextView) view.findViewById(R.id.buybtn);
        this.sharebtn = (TextView) view.findViewById(R.id.sharebtn);
        this.price_curr = (TextView) view.findViewById(R.id.price_curr);

    }
}

}

最佳答案

getLocation() 返回 0,因为 View 尚未布局。您需要设置布局监听器:

final View view = holder.horiz_progress;
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
         // Do what you need to do here.
         // Then remove the listener:
         view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }

});

关于android - 获取屏幕上的位置以便在 View 持有者中查看,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32949635/

相关文章:

android - 添加按钮到 android.view.View

java - 在适配器上为每个项目添加 Onclick 以打开新的不同 Activity

android - RecyclerView ViewHolders 中的许多 CountDownTimer 出错

android - 用于列表项更新的 ListView 适配器 onClickListener

android - 如何禁用 ViewHolder 中的 onLongPressListener?

android - EditText 提示未显示(Java - android)

android - sqlite3数据库建表报错

android - 带有使用 OkHttp3 3.3.1 的外部 AAR 的 Retrofit2 NoSuchMethodError

android - RecyclerView lateinit 属性 mClickListener 尚未初始化

android - 在 RecyclerView Adapter 中使用带有 Activity 作为参数的方法