我正在尝试实现一个实现 ConstraintLayout 的自定义类,但问题是,当我尝试在 XML 中使用它时,Android Studio 只是挂起,一切都卡住了,你无法执行任何操作,你可以关闭Studio 通过任务管理器。然后您重新打开,但如果您打开该 XML 文件,又会出现同样的情况。
我明白了: 渲染布局时预览超时。当某个自定义 View 中存在无限循环或无界递归时,通常会发生这种情况。
基本上,首先我通过 ConstraintLayout 设计了 UI,然后我尝试用这个类替换 ConstraintLayout,然后当它尝试渲染时它就卡住了。由于保密协议(protocol),我无法提供太多代码。
类(class):
public class ExtraView extends ConstraintLayout {
public ExtraView(Context context) {
super(context);
init(context);
}
public ExtraView (Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ExtraView (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public void init(Context context){
View v = LayoutInflater.from(context).inflate(R.layout.view_extra_rent_booking, this, true);
Butterknife.bind(this,v);
}
}
XML
<package.ExtraView 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:id="@+id/rentExtraLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="@color/white">
<TextView
android:id="@+id/nameTextView"
style="@style/contentTextDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginStart="40dp"
android:layout_marginTop="18dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/gps_extra" />
<ImageView
android:id="@+id/checkImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:src="@drawable/icon_checkmark_dark"
app:layout_constraintBottom_toBottomOf="@+id/nameTextView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/nameTextView" />
<TextView
android:id="@+id/priceTextView"
style="@style/contentTextDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
app:layout_constraintRight_toLeftOf="@+id/checkImageView"
app:layout_constraintTop_toTopOf="@+id/nameTextView"
tools:text="+xx€" />
<View
android:id="@+id/lineSplitting"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:layout_marginTop="10dp"
android:background="@color/green"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="@+id/nameTextView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nameTextView" />
<LinearLayout
android:id="@+id/expandViewLinearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lineSplitting"></LinearLayout>
</package.ExtraView>
这将使 Android Studio 挂起,并且打开此 xml 时应用程序将崩溃。但使用 ConstraintLayout 就可以了。我究竟做错了什么?我已经下载了最新的库。
最佳答案
我再次重新阅读了对话,并意识到您只是希望呈现的布局成为 RecycleView 项目。我告诉您有关 fragment 的信息是因为我认为您想将数据列表放入额外 View 中。 (所以我对此表示歉意:/)
如果您想保留此 View 序列以供多种用途,这是制作个性化 View 的最佳选择。
对于个性化 View ,问题是使用模式构建 View 。为此,一种方法是手动执行此操作,因为您在一个级别上有一系列 View 。
public class ExtraView extends ConstraintLayout { private TextView mText = null; ... public void init(Context context){ int wrapContent = LayoutParams.WRAP_CONTENT; int matchParent = LayoutParams.MATCH_PARENT; setLayoutParams(new LayoutParams(matchParent, wrapContent)); mText = new TextView(getContext()); addView(mText, new LinearLayout.LayoutParams(wrapContent, wrapContent)); ... // Do the same thing for all elements with parameters } }
之后添加您的 addExtra
方法,就可以了,不再循环,您可以在您想要的地方和 onBindViewHolder 中使用它只有一行。
编辑:
如果替换根节点,则使用实际布局 XML,完整示例:
Extraview.java 文件
public class ExtraView extends ConstraintLayout {
public ExtraView(Context context) {
super(context);
init(context);
}
public ExtraView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ExtraView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public void init(Context context) {
View v = LayoutInflater.from(context).inflate(R.layout.view_extra_rent_booking, this, true);
ButterKnife.bind(this, v);
}
public void addData(Object data) {
Log.e(getClass().getSimpleName(), object.toString());
}
}
view_extra_rent_booking.xml 文件
<merge 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:id="@+id/rentExtraLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true">
<TextView
android:id="@+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginStart="40dp"
android:layout_marginTop="18dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="test" />
<ImageView
android:id="@+id/checkImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:layout_constraintBottom_toBottomOf="@+id/nameTextView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/nameTextView" />
<TextView
android:id="@+id/priceTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
app:layout_constraintRight_toLeftOf="@+id/checkImageView"
app:layout_constraintTop_toTopOf="@+id/nameTextView"
android:text="test" />
<View
android:id="@+id/lineSplitting"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:layout_marginTop="10dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="@+id/nameTextView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nameTextView" />
<LinearLayout
android:id="@+id/expandViewLinearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lineSplitting">
</LinearLayout>
</merge>
主要 Activity 仅供示例,但实际上是您holder在onBindViewHolder()中获取 View
activity_main.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<com.kunzisoft.myapplication.ExtraView 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:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.kunzisoft.myapplication.MainActivity" />
MainActivity.java 文件
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExtraView itemData = (ExtraView) findViewById(R.id.item);
itemData.addData("OUIIIIIII");
}
}
关于android - 具有约束布局的自定义类,Android Studio 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45041483/