我在考虑从文件中膨胀XML对象,它基本上是一个ConstraintLayout
,里面有一些TextView。但是通过像这样扩展ConstraintLayout,并使用以下内容代替ConstraintLayout:
public class CommonLayout extends ConstraintLayout {
private TextView myTitle;
private TextView myDesc;
public CommonLayout(@NonNull Context context) {
super(context);
loadWidgets();
}
public CommonLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
loadWidgets();
}
public CommonLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
loadWidgets();
}
public CommonLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
loadWidgets();
}
private void loadWidgets() {
myTitle = this.findViewById(R.id.layoutTitle);
myDesc = this.findViewById(R.id.layoutDesc);
}
// ----
public void setMyTitle(String input) {
myTitle.setText(input);
}
public void setMyDescription(String input) {
myDesc.setText(input);
}
}
我想扩展ConstraintLayout可能看起来很奇怪,我知道......重要的是我可以膨胀这些ConstraintLayout子级(基本上是ConstraintLayout的克隆,它使用一些方法在XML“CommonLayout”文件中查找默认TextViews并设置其文本--换句话说,将子视图逻辑隔离并封装在CommonLayout本身中)。如果它能工作,那么我将使用更多ConstraintLayout子级和一个通用接口来应用polimorfism。
**要点是将膨胀的“CommonLayout“加载到某个LinearLayout中。这些“CommonLayout”将包含我想动态设置的TextView,这些CommonLayout对象将总是从view_commonlayout.xml
文件膨胀。**如果这样做有效,我想用不同的ConstraintLayout子级来升级它。“但是为什么要扩展ConstraintLayout呢?可以吗?"难道您不应该为此而膨胀普通的ConstraintLayout
吗?”嗯......也许......但如果我出于某种原因需要为所有子对象提供一个公共接口,我可以通过扩展ConstraintLayout,在情况需要时立即添加implements I_SomeCommonInterface
以应用polimorfism......或者至少是这样的想法
......然后,我想或多或少地这样使用它:
// ...from some fragment...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.the_fragment, container, false);
// XXX The point is inflating CommonLayouts into this LinearLayout
LinearLayout mainLayout = view.findViewById(R.id.theLinearLayout);
//CommonLayout obj1 = new CommonLayout(getContext());
CommonLayout obj1 = (CommonLayout) LayoutInflater.from(view.getContext()).inflate(R.layout.view_commonlayout, mainLayout, false);
obj1.setMyTitle("Good morning");
obj1.setMyDescription(getString(R.string.lorem_ipsum));
mainLayout.addView(obj1);
return view;
}
我想从这个XML view_commonlayout.xml
文件加载每个CommonLayout:
<com.mydomain.myapp.views.custom_widgets.CommonLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
android:layout_marginHorizontal="10dp"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/layoutTitle"
android:textColor="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Here goes THE TITLE"
tools:layout_editor_absoluteX="15dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:textSize="24sp"/>
<TextView
android:id="@+id/layoutDesc"
android:textColor="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Here goes the description"
tools:layout_editor_absoluteX="15dp"
app:layout_constraintTop_toBottomOf="@id/layoutTitle"
app:layout_constraintStart_toStartOf="parent"
android:textSize="12sp"/>
</com.mydomain.myapp.views.custom_widgets.CommonLayout>
我做错了什么来实现我在这里尝试的?当使用setMyTitle
和setMyDescription
时,NullPointerException
总是会失败(我现在开始做整个事情的第一个“多米诺堆栈测试”,在解决NullpointerException
后,其他一些事情可能会失败,但现在这是我首先关心的问题...)
至少,我知道,(通过TraceBack)myTitle
变量是空的。所以,this.findViewById()
失败了。可能是因为我不知道如何从XML文件膨胀并将其全部保存在同一个类中(显然,我的LayoutInflater.inflate(params)
尝试仍然使它以与使用new
操作符相同的方式失败)。我被困在那里了...
澄清:
计划的视图结构并不打算加载任何类型的数据,既不从数据库也不从任何用户首选项或任何东西。目的是使一个“动态主菜单”与此。
现在,如果它能用,我会用几个静态选项填充它。但是,在将来,我可能会根据用户使用应用的历史来使它变得有点动态。但是现在,我很高兴如果我能用计划的结构或类似的结构来完成这件事。
我的想法还是有可能会失效。我希望,如果我膨胀一些XML文件(如view_commonlayout.xml
)我可以将它赋给XML文件的顶级父变量类型(在本例中为CommonLayout),并从那里访问(文本视图)。也许,只是也许,在CommonLayout
类本身中封装此XML结构的行为以及与之相关的所有内容。(即使我不确定所有的实现细节)。这些疯狂的想法中的一些可能是不可行的,如果是这样的话,我将不得不寻找一些解决方案。也许我应该尝试不同的方法,比如创建一个新的“ Package 类”而不是扩展ConstraintLayout?
目的
这一切都是为了给我已经发布在Google Play商店的应用增加一个新功能,类似于“动态登陆菜单”,以吸引用户对我的应用的一些最重要功能的注意。我想分享这个链接,但它只在我的祖国可用,我不确定这是否有助于澄清这个问题。
这就像我为每个公共布局创建了几个选项,带有选项标题和选项描述。加载的每个CommonLayout都有其OnClickListener来或多或少地打开某个菜单。现在我只对一种类型的XML结构感到满意(view_commonlayout.xml
中的一个),但将来我希望使用类似ConstraintLayout的父级来提供其他XML结构,但是不同的子视图(例如,不是两个TextView,而是一个ImageView和一个TextView;或者可能是一些小型表单来提交一些东西...在这种情况下,我可能需要提取一个公共接口来应用polimorfism(例如,使用方法setOnClickListener
或setLayoutTitle
或类似的东西来拥有所有公共接口...))。
NullPointerException
已解决
最后,解决NullPointerException
比我想象的要容易......我不确定这个解决方案是否优雅,但它起作用了。我只需要稍微修改CommonLayout
类,去掉loadWidgets
方法,并像这样修改setter:
public void setMyTitle(String input) {
myTitle = this.findViewById(R.id.layoutTitle);
myTitle.setText(input);
}
public void setMyDescription(String input) {
myDesc = this.findViewById(R.id.layoutDesc);
myDesc.setText(input);
}
尽管它解决了导致应用崩溃的问题,但现在自我回答这个问题还为时过早。我仍然需要弄清楚我是否可以将膨胀的CommonLayout
变成一个按钮(可能不会那么难)......而且,我想扩展ConstraintLayout的全部意义只是我可以强制孩子实现一个接口(这让我考虑编辑这个问题的标题)
1条答案
按热度按时间o0lyfsai1#
简短的回答是:是的,您可以扩展ConstraintLayout,像普通ConstraintLayout一样使用XML资源文件中的子元素,似乎一切都与您对CostraintLayout的期望一样。
我想从这里得到一个更详细的答案,关于多态性的优点,但是我需要更多的时间。