【问题标题】:circular auto scrolling horizontalscrollview android圆形自动滚动horizo​​ntalscrollview android
【发布时间】:2015-04-17 08:03:24
【问题描述】:

我想自动滚动一个水平滚动视图,它在线性布局中包含很多图像视图 当它到达最后一个图像视图时,第一个出现,依此类推

我发现 this code 符合我的需求,但是当我添加自动滚动时,循环功能将不起作用:到达最后一个 imageview 时,第一个不会出现

这是我的代码:

slider = (RelativeLayout)findViewById(R.id.slider);
    RelativeLayout container = (RelativeLayout) findViewById(R.id.slider);
    scrollView = new PSInfiniteScrollView(this,new PSSize(120,120));
    for (int i = 0; i < 10; i++) {
        MyCloneableView img = new MyCloneableView(this);
        img.setId(i + 20);
        img.setImageResource(R.drawable.ic_launcher);
        img.setScaleType(ImageView.ScaleType.FIT_XY);
        img.setBackgroundColor(c[i]);
        img.setTag(c[i]);
        scrollView.addItem(img);
    }

    container.addView(scrollView);

    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            doLoop();
        }
    });

    t.start();

这里还有doLoop方法:

private void doLoop(){
    do {
        scrollView.scrollBy(2, 0);
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        scrollView.scrollBy(2, 0);
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }   while (true);
}   

【问题讨论】:

    标签: android horizontalscrollview


    【解决方案1】:

    我通过使用带有水平线性布局管理器的 RecyclerView 实现了类似的要求 这里是可以帮助你的代码sn-ps

    1. 要使回收器视图显示为水平,请使用 LinearLayout 管理器并将其方向设置为水平

      mLinearLayoutManager = new LinearLayoutManager(context);
      mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
      mRecyclerView.setLayoutManager(mLinearLayoutManager);
      
    2. 使其循环:在您的 Recycler View 适配器中使 getItemCount 返回一个非常大的值,例如 Integer.MAX_VALUE

      @Override
      public int getItemCount() {
          return Integer.MAX_VALUE;
      }
      

    要获取适配器中的实际项目,您可以使用像这样的简单模数运算

    @Override
    public void onBindViewHolder(ActionItemViewHolder holder, int position) {
        position = position % ACTUAL_SIZE_OF_LIST;
    };
    

    这是让它循环的诀窍!

    使您的 RecyclerView 滚动到一个索引,该索引是您的适配器 getItemCount 返回值的一半,您可以通过以下代码实现此目的:

    mLinearLayoutManager.scrollToPosition(Integer.MAX_VALUE / 2);

    (这是一个简单的 hack)

    我不明白你所说的自动滚动到底是什么意思,如果你想让项目在点击它时滚动到屏幕中心,这里是代码

    private void scrollToCenter(View v) {
        int itemToScroll = mRecyclerView.getChildPosition(v);
        int centerOfScreen = mRecyclerView.getWidth() / 2 - v.getWidth() / 2;
        mLayoutManager.scrollToPositionWithOffset(itemToScroll, centerOfScreen);
    }
    

    希望对您有所帮助!

    【讨论】:

    • 我的意思是自动滚动:图像在没有手动滚动的情况下移动,当到达最后一个时,第一个出现在它之后,依此类推,你明白吗?
    【解决方案2】:

    在这里,我创建了一个带有自动滚动功能的回收站视图

    public class AdsViewer extends FrameLayout {
    
    private static final String TAG = "AdsViewer";
    
    private final long SWITCH_TIME = 5000;
    @BindView(R.id.ads_recycler_view)
    RecyclerView adsRecyclerView;
    
    private AdsAdapter adsAdapter;
    
    private int currentItem = 0;
    
    private Handler switchHandler = new Handler();
    private Runnable switchRunnable = new Runnable() {
        @Override
        public void run() {
            showNextAd();
        }
    };
    
    public AdsViewer(@NonNull Context context) {
        super(context);
        init();
    }
    
    public AdsViewer(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    private void init() {
        inflate(getContext(), R.layout.ads_viewer, this);
        ButterKnife.bind(this);
        initRecyclerView();
    }
    
    private void initRecyclerView() {
        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        adsRecyclerView.setLayoutManager(linearLayoutManager);
    
        adsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                currentItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
                resetTimer();
            }
        });
    
        // add pager behavior, Add this to have paging scrolling
        //PagerSnapHelper snapHelper = new PagerSnapHelper();
        //snapHelper.attachToRecyclerView(adsRecyclerView);
    }
    
    private void resetTimer() {
        switchHandler.removeCallbacks(switchRunnable);
        switchHandler.postDelayed(switchRunnable, SWITCH_TIME);
    }
    
    public void clear() {
        if (adsAdapter != null) {
            adsAdapter.clear();
        }
    }
    
    public void setAds(List<Ads> ads) {
        if (adsAdapter == null || ads.size() != adsAdapter.getItemCount()) {
            initializeAdapter();
            adsAdapter.addItems(ads);
            resetTimer();
        }
    }
    
    private void initializeAdapter() {
        adsAdapter = new AdsAdapter(LayoutInflater.from(getContext()));
        adsRecyclerView.setAdapter(adsAdapter);
    }
    
    private void showNextAd() {
        int adsCount = adsAdapter.getItemCount();
        if (adsCount > 1) {
            if (currentItem == (adsCount - 1)) {
                currentItem = 0;
                adsRecyclerView.scrollToPosition(currentItem);
                resetTimer();
            } else {
                currentItem++;
                adsRecyclerView.smoothScrollToPosition(currentItem);
            }
        }
    }
    }
    
    • SWITCH_TIME是滚动时间
    • onScrollStateChanged 用于在用户滚动时重置计时器。
    • 我对所有过渡都使用 smoothScrollToPosition,但从第一个到最后一个除外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多