ScrollView用法

本文介绍了一个基于Android的示例项目,该项目展示了如何通过监听ScrollView的滚动事件来实现在LinearLayout中动态添加视图组件,并自动滚动到新添加的组件位置。文章详细解释了通过按钮点击事件来触发这一过程的方法。
package com.example.scrollview;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private ScrollView sView;
	private LinearLayout linearLayout;
	private Button button;
	private TextView textView;
	private Handler myHandler = new Handler();
	//当前滚屏的高度
	private int sHeight ;
	private Intent myIntent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		sView = (ScrollView)findViewById(R.id.scrollView);
		linearLayout = (LinearLayout)findViewById(R.id.linearLayout);
		button = (Button)findViewById(R.id.button);
		textView = (TextView)findViewById(R.id.textView);
		sHeight = sView.getHeight();
		
		button.setOnClickListener(new myOnclickListener());
	}
	
	/**
	 * button事件:
	 * 1.点击button在linearlayout中动态添加textView和button
	 * 2.触发ScrollView的滚屏操作,滚动到最新添加的button处
	 *
	 */
	class myOnclickListener implements OnClickListener{

		int index = 0;
		
		@Override
		public void onClick(View v) {
			LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
					LinearLayout.LayoutParams.WRAP_CONTENT);
			
			TextView addText = new TextView(MainActivity.this);
			addText.setText("textView"+index);
			
			Button addButton = new Button(MainActivity.this);
			addButton.setText("button"+index);
			addButton.setId(index++);

			linearLayout.addView(addText, linearLayoutParams);
			linearLayout.addView(addButton, linearLayoutParams);
		
			myHandler.post(mScrollToButton);
		}
		
	}
	
	private Runnable mScrollToButton = new Runnable() {
		
		@Override
		public void run() {
			
			//linearLayout的总高度
			System.out.println("linearLayout.getMeasuredHeight() =>"+linearLayout.getMeasuredHeight());
			//定位:位置 = 总高度 - 当前屏幕的高度
			int off = linearLayout.getMeasuredHeight() - sHeight;
			if(off > 0){
				//向下滚屏
				sView.scrollBy(0, off);
			}
			
		}
	};

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}

 

在 Android 开发中,`CoordinatorLayout` 是一个强大的布局容器,它与 `ScrollView` 或 `NestedScrollView` 的联动机制,可以实现复杂的交互效果,例如滚动隐藏工具栏、浮动按钮的动态行为等。以下是实现 `CoordinatorLayout` 与 `ScrollView` 联动的基本方法和示例。 ### 基本结构 在布局文件中,通常使用 `CoordinatorLayout` 作为根布局,其中包含 `AppBarLayout` 和 `NestedScrollView`。`NestedScrollView` 用于包裹需要滚动的内容,而 `AppBarLayout` 中可以放置 `Toolbar`、`TabLayout` 等组件,实现联动效果。 ```xml <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/app_bar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways"/> </com.google.android.material.appbar.AppBarLayout> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 可滚动的内容 --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Scrollable Content" android:textSize="24sp" android:padding="16dp"/> <!-- 更多内容 --> </LinearLayout> </androidx.core.widget.NestedScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout> ``` ### 关键属性说明 - **`app:layout_scrollFlags`**:定义 `AppBarLayout` 中子视图的滚动行为。例如: - `scroll`:表示该视图会随内容滚动而滚动。 - `enterAlways`:表示当内容向下滚动时,该视图会优先显示。 - `snap`:滚动结束后,视图会根据滚动位置自动调整其状态。 - **`app:layout_behavior="@string/appbar_scrolling_view_behavior"`**:这是 `NestedScrollView` 必须设置的属性,它告诉 `CoordinatorLayout` 当前视图需要与 `AppBarLayout` 联动。 ### 自定义 Behavior 如果需要更复杂的联动行为,可以通过继承 `CoordinatorLayout.Behavior` 来实现自定义的 `Behavior` 类。例如,可以监听 `NestedScrollView` 的滚动事件,并根据滚动位置调整其他视图的位置或状态。 ```java public class CustomBehavior extends CoordinatorLayout.Behavior<View> { public CustomBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) { return axes == ViewCompat.SCROLL_AXIS_VERTICAL; } @Override public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { // 根据滚动事件调整 child 的位置 child.setTranslationY(child.getTranslationY() - dyConsumed); } } ``` 然后在布局文件中为需要应用该行为的视图设置: ```xml <View android:id="@+id/custom_view" android:layout_width="match_parent" android:layout_height="100dp" app:layout_behavior=".CustomBehavior"/> ``` ### 注意事项 - `NestedScrollView` 是 `ScrollView` 的增强版本,支持嵌套滚动,因此推荐使用 `NestedScrollView` 替代传统的 `ScrollView`。 - 在 `CoordinatorLayout` 中,`AppBarLayout` 应该作为第一个子视图,这样可以确保它在滚动时能够正确地与其他视图互动。 - 如果 `CoordinatorLayout` 中嵌套了横向的 `ViewPager2`,可能会导致嵌套滑动失效的问题。可以通过禁用 `ViewPager2` 内部 `RecyclerView` 的嵌套滚动来解决: ```kotlin viewPager2.children.find { it is RecyclerView }?.let { (it as RecyclerView).isNestedScrollingEnabled = false } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值