You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何实现每条可跳转详情页的新闻Marquee并解决传参问题

解决Android跑马灯(Marquee)单条新闻点击传值的问题

嘿,我明白你遇到的问题了——用TextView做跑马灯时,没法把点击的单条新闻内容传到下一个页面对吧?其实核心问题是单个TextView拼接所有新闻的方式,没法区分点击的是哪一条。我给你推荐一个更靠谱的方案,用RecyclerView来实现可点击的跑马灯,每条新闻都是独立的可点击项,传值就简单多了!

一、先准备新闻数据模型

我们先定义一个News类,用来存储每条新闻的标题和详情信息(比如链接或者内容):

public class News {
    private String title;
    private String detailUrl; // 也可以换成存储详情文本

    public News(String title, String detailUrl) {
        this.title = title;
        this.detailUrl = detailUrl;
    }

    // Getter方法,供外部获取数据
    public String getTitle() {
        return title;
    }

    public String getDetailUrl() {
        return detailUrl;
    }
}

二、创建单条新闻的布局

新建item_news.xml,作为每条新闻的UI模板,这里用一个TextView显示标题:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_news_title"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:paddingHorizontal="16dp"
    android:gravity="center_vertical"
    android:textSize="16sp"
    android:singleLine="true"/>

三、实现RecyclerView的Adapter

Adapter负责绑定数据,并且给每条新闻添加点击事件,点击时把对应的News对象传递出去:

public class NewsMarqueeAdapter extends RecyclerView.Adapter<NewsMarqueeAdapter.NewsViewHolder> {
    private List<News> newsList;
    private OnNewsItemClickListener clickListener;

    // 定义点击回调接口
    public interface OnNewsItemClickListener {
        void onNewsClick(News news);
    }

    public NewsMarqueeAdapter(List<News> newsList, OnNewsItemClickListener listener) {
        this.newsList = newsList;
        this.clickListener = listener;
    }

    @NonNull
    @Override
    public NewsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_news, parent, false);
        return new NewsViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull NewsViewHolder holder, int position) {
        News currentNews = newsList.get(position);
        holder.tvNewsTitle.setText(currentNews.getTitle());
        // 给整个新闻项设置点击事件
        holder.itemView.setOnClickListener(v -> clickListener.onNewsClick(currentNews));
    }

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

    // ViewHolder类,缓存控件
    static class NewsViewHolder extends RecyclerView.ViewHolder {
        TextView tvNewsTitle;

        public NewsViewHolder(@NonNull View itemView) {
            super(itemView);
            tvNewsTitle = itemView.findViewById(R.id.tv_news_title);
        }
    }
}

四、在主页面配置RecyclerView实现跑马灯效果

设置横向布局,再添加自动滚动的逻辑,同时处理点击跳转:

public class MainActivity extends AppCompatActivity implements NewsMarqueeAdapter.OnNewsItemClickListener {
    private RecyclerView rvNewsMarquee;
    private NewsMarqueeAdapter adapter;
    private List<News> newsDataList;
    private Handler scrollHandler;
    private Runnable scrollRunnable;
    private int scrollSpeed = 2; // 滚动速度,数值越大越快,可自行调整

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rvNewsMarquee = findViewById(R.id.rv_news_marquee);

        // 初始化新闻数据
        newsDataList = new ArrayList<>();
        newsDataList.add(new News("第一条新闻:Android跑马灯实现点击跳转", "detail_page_1"));
        newsDataList.add(new News("第二条新闻:解决单条新闻传值难题", "detail_page_2"));
        newsDataList.add(new News("第三条新闻:自定义跑马灯组件最佳实践", "detail_page_3"));

        // 设置RecyclerView为横向布局
        LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        rvNewsMarquee.setLayoutManager(horizontalLayoutManager);
        adapter = new NewsMarqueeAdapter(newsDataList, this);
        rvNewsMarquee.setAdapter(adapter);

        // 启动自动滚动
        startAutoScroll();
    }

    private void startAutoScroll() {
        scrollHandler = new Handler();
        scrollRunnable = new Runnable() {
            @Override
            public void run() {
                // 只有当RecyclerView处于空闲状态时才滚动
                if (rvNewsMarquee.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                    rvNewsMarquee.smoothScrollBy(scrollSpeed, 0);
                }
                scrollHandler.postDelayed(this, 16); // 约60帧/秒,保证滚动流畅
            }
        };
        // 延迟1秒再开始滚动,给用户一点阅读时间
        scrollHandler.postDelayed(scrollRunnable, 1000);
    }

    // 实现点击回调,跳转到详情页并传递数据
    @Override
    public void onNewsClick(News news) {
        Intent detailIntent = new Intent(this, NewsDetailActivity.class);
        detailIntent.putExtra("NEWS_TITLE", news.getTitle());
        detailIntent.putExtra("NEWS_DETAIL_URL", news.getDetailUrl());
        startActivity(detailIntent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 页面销毁时停止滚动,避免内存泄漏
        if (scrollHandler != null && scrollRunnable != null) {
            scrollHandler.removeCallbacks(scrollRunnable);
        }
    }
}

五、主页面布局(activity_main.xml)

把RecyclerView放在布局里,设置合适的高度:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#f5f5f5"
    android:paddingVertical="8dp">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_news_marquee"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:overScrollMode="never"/> <!-- 去掉滚动到边缘的波纹效果 -->

</LinearLayout>

六、详情页面接收数据

在NewsDetailActivity里获取传递过来的新闻数据,展示详情:

public class NewsDetailActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_news_detail);

        TextView tvDetailTitle = findViewById(R.id.tv_detail_title);
        TextView tvDetailContent = findViewById(R.id.tv_detail_content);

        // 获取从主页面传递过来的新闻数据
        String newsTitle = getIntent().getStringExtra("NEWS_TITLE");
        String newsDetailUrl = getIntent().getStringExtra("NEWS_DETAIL_URL");

        tvDetailTitle.setText(newsTitle);
        // 这里可以根据detailUrl加载网页,或者显示本地详情文本
        tvDetailContent.setText("详情页面内容:" + newsDetailUrl);
    }
}

补充说明

如果你坚持想用原生TextView的Marquee方式,需要手动计算每条新闻文本在TextView中的位置范围,点击时根据坐标判断属于哪条新闻——这种方式不仅复杂,还容易因为文本换行、字体大小变化出问题,远不如RecyclerView的方案稳定灵活。

内容的提问来源于stack exchange,提问作者zzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:47:16