源码: github.com/androidx/co… 摘录部分代码块:
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
}
获取系统所有xml 文件名:
private static String[] getLayouts(Test filter) {
ArrayList<String> list = new ArrayList<>();
Field[] f = R.layout.class.getDeclaredFields();
Arrays.sort(f, (f1, f2) -> {
int v = (REVERSE ? -1 : 1) * f1.getName().compareTo(f2.getName());
if (SHOW_FIRST == null) {
return v;
}
if (f1.getName().matches(SHOW_FIRST)) {
return -1;
}
if (f2.getName().matches(SHOW_FIRST)) {
return +1;
}
return v;
});
for (int i = 0; i < f.length; i++) {
String name = f[i].getName();
if (filter == null || filter.test(name)) {
list.add(name);
}
}
return list.toArray(new String[0]);
}
拿到所有demo的xml文件之后,可以动态设置setContentView
,实现一个activity
运行多个布局
private void setupActivity(Bundle extra) {
//layout name
String prelayout = extra.getString(Loader.KEY);
layout_name = prelayout;
Context ctx = getApplicationContext();
//layout id
int id = ctx.getResources().getIdentifier(prelayout, "layout", ctx.getPackageName());
//设置全屏模式
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ActionBar bar = getSupportActionBar();
if (bar != null) {
bar.hide();
}
//设置内容布局
setContentView(id);
ActionBar actionBar = getSupportActionBar();
actionBar.setBackgroundDrawable(new ColorDrawable(0xFFfd401d));
ViewGroup root = ((ViewGroup) findViewById(android.R.id.content).getRootView());
View mlView = findViewById(R.id.motionLayout);
mMotionLayout = (mlView != null) ? (MotionLayout) mlView : Loader.findMotionLayout(root);
}
旋转视图:
//Setup the Carousel adapter
/**
* Adapter for a Carousel
*/
public interface Adapter {
/**
* Number of items you want to display in the Carousel
* @return number of items 总数
*/
int count();
/**
* Callback to populate the view for the given index
* 相当于getview
* @param view
* @param index
*/
void populate(View view, int index);
/**
* Callback when we reach a new index
* @param index
*/
void onNewItem(int index);
}
MotionLayout 仅适用于其直接子级,不支持嵌套布局层次结构或 Activity 转换、
app:layoutDescription
引用的是MotionScene
包含布局的运动描述,
developer.android.google.cn/training/co…
MotionLayout 属性
app:showPaths="boolean"
表示在运动进行时是否显示运动路径
app:motionDebug="SHOW_ALL"
显示与运动有关的其他调试信息
demo_010_carousel.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/motionLayout"
app:showPaths="true"
app:layoutDescription="@xml/demo_010_carousel_scene">
<ImageView
android:id="@+id/imageView0"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginEnd="16dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView1"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/goldengate" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginEnd="16dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView2"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/bryce_canyon" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/fitzgerald_marine_reserve"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="16dp"
android:scaleType="centerCrop"
android:src="@drawable/death_valley"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView2"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView4"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="16dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView3"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/goldengate" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="100dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="100dp" />
<androidx.constraintlayout.helper.widget.Carousel
android:id="@+id/carousel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:carousel_forwardTransition="@+id/forward"
app:carousel_backwardTransition="@+id/backward"
app:carousel_previousState="@+id/previous"
app:carousel_nextState="@+id/next"
app:carousel_infinite="true"
app:carousel_firstView="@+id/imageView2"
app:constraint_referenced_ids="imageView0,imageView1,imageView2,imageView3,imageView4" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="36dp"
android:text="go to last item"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
对应的需要layoutDescription, demo_010_carousel_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@id/start"
motion:constraintSetEnd="@+id/next"
motion:duration="1000"
android:id="@+id/forward">
<KeyFrameSet>
</KeyFrameSet>
<OnSwipe
motion:dragDirection="dragLeft"
motion:touchAnchorSide="left" />
</Transition>
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/previous"
android:id="@+id/backward">
<OnSwipe
motion:dragDirection="dragRight"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="@+id/previous">
<Constraint
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="@id/guideline2"
android:id="@+id/imageView2"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp" />
<Constraint
android:id="@+id/imageView3"
motion:layout_constraintStart_toEndOf="@+id/imageView2"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp" />
<Constraint
android:id="@+id/imageView1"
motion:layout_constraintEnd_toStartOf="@id/guideline2"
android:layout_width="0dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="16dp"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toEndOf="@id/guideline"
motion:layout_constraintDimensionRatio="1:1"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp" />
<Constraint
android:id="@+id/imageView0"
motion:layout_constraintEnd_toStartOf="@id/guideline"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="16dp"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/start">
<Constraint
motion:layout_constraintEnd_toEndOf="@id/guideline2"
android:layout_width="0dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="@id/guideline"
android:id="@+id/imageView2"
motion:layout_constraintDimensionRatio="w,1:1"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp" />
<Constraint
android:id="@+id/imageView3"
motion:layout_constraintStart_toEndOf="@id/guideline2"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="16dp"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/imageView1"
motion:layout_constraintEnd_toStartOf="@id/guideline"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="16dp"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/next">
<Constraint
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toTopOf="parent"
android:id="@+id/imageView2"
motion:layout_constraintEnd_toStartOf="@id/guideline"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp" />
<Constraint
android:id="@+id/imageView3"
motion:layout_constraintStart_toEndOf="@id/guideline"
android:layout_width="0dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="16dp"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintEnd_toStartOf="@id/guideline2"
android:layout_marginEnd="16dp"
motion:layout_constraintDimensionRatio="1:1"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp" />
<Constraint
android:id="@+id/imageView4"
motion:layout_constraintStart_toEndOf="@id/guideline2"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="16dp"
motion:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
</ConstraintSet>
</MotionScene>
CircularFlow
环形布局
activity_circular_flow_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CircularFlowDemoActivity">
<View
android:id="@+id/view1"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view2"
android:layout_width="50dp"
android:layout_height="10dp"
android:background="@android:color/darker_gray" />
<View
android:id="@+id/view3"
android:layout_width="50dp"
android:layout_height="10dp"
android:background="@android:color/holo_red_dark" />
<View
android:id="@+id/view4"
android:layout_width="50dp"
android:layout_height="10dp"
android:background="@android:color/holo_green_dark" />
<View
android:id="@+id/view5"
android:layout_width="50dp"
android:layout_height="10dp"
android:background="@android:color/holo_blue_dark" />
<View
android:id="@+id/view6"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:background="@android:color/holo_orange_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<View
android:id="@+id/view7"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:background="@android:color/holo_purple"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view8"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@android:color/holo_green_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view9"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="136dp"
android:background="@android:color/holo_green_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view10"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="116dp"
android:layout_marginEnd="116dp"
android:background="@android:color/holo_green_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view11"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="116dp"
android:layout_marginEnd="216dp"
android:background="@android:color/holo_green_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view12"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="161dp"
android:layout_marginEnd="216dp"
android:background="@android:color/holo_green_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view13"
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="161dp"
android:layout_marginEnd="416dp"
android:background="@android:color/holo_red_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.helper.widget.CircularFlow
android:id="@+id/circularFlow"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:circularflow_angles="10, 40, 80, 135"
app:circularflow_defaultAngle="45"
app:circularflow_defaultRadius="10dp"
app:circularflow_radiusInDP="110, 150, 170, 190"
app:circularflow_viewCenter="@+id/view1"
app:constraint_referenced_ids="view13,view2,view3,view4,view5,view6,view7,view8,view9,view10,view11,view12" />
</androidx.constraintlayout.widget.ConstraintLayout>
CircularFlowDemoActivity.kt
package androidx.constraintlayout.experiments
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.helper.widget.CircularFlow
class CircularFlowDemoActivity : AppCompatActivity() {
var views = intArrayOf(
R.id.view2,
R.id.view3,
R.id.view4,
R.id.view5,
R.id.view6,
R.id.view7,
R.id.view8,
R.id.view9,
R.id.view10,
R.id.view11,
R.id.view12,
R.id.view13
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_circular_flow_demo)
val circularFlow = findViewById<CircularFlow>(R.id.circularFlow)
findViewById<View>(R.id.view1).setOnClickListener {
views.indices.forEach { i ->
val view = findViewById<View>(views[i])
circularFlow.updateReference(view, 120, i * 30f)
view.rotation = 90 - (360 - i * 30f)
}
}
}
}