我有一个小问题。我试图在我的 RecyclerView 中显示多个不同的布局。我设法以两种不同的方式做到了这一点。但我觉得我的代码和逻辑可以看起来好多了
我的项目本身遵循 MVVM 设计模式。所以我使用本机数据绑定。这就是为什么我的逻辑变得有问题的原因。
第一种方法
我尝试这样做的第一种方法只是将所有内容压缩到一个大的布局文件中。然后根据帖子的类型隐藏和显示。
private void onBindImagePost(CommentFeedViewHolder holder, CommentFeedItem item) {
holder.mBinding.adapterCommentFeedDraweeView.setVisibility(View.VISIBLE);
holder.mBinding.adapterCommentFeedTopic.setVisibility(View.VISIBLE);
holder.mBinding.adapterCommentFeedYoutubeContainer.setVisibility(View.GONE);
holder.mBinding.adapterCommentFeedVideoContainer.setVisibility(View.GONE);
holder.mBinding.adapterCommentFeedPieChartContainer.setVisibility(View.GONE);
holder.mBinding.adapterCommentFeedDraweeView.setImageURI(item.getUri());
}
Run Code Online (Sandbox Code Playgroud)
所以首先我只是显示和隐藏正在使用和没有使用的视图。我还为一些视图添加了额外的逻辑。
这个解决方案感觉非常糟糕,因为它包含了很多硬编码,并且业务逻辑被添加到片段中。
第二种方法
我为每个帖子添加了一个新的布局文件。他们都有自己的绑定。这最大限度地减少了代码。
if (item.getType() == POST_TEXT) {
AdapterFeedType1Binding binding = DataBindingUtil.inflate(inflater,R.layout.adapter_feed_type_1,holder.binding.mainFrame,true);
binding.setGameFeedItem(item);
}
Run Code Online (Sandbox Code Playgroud)
但是有更好的方法吗?所以我不必为每种类型的帖子创建一个新的绑定类?
嗨,我的问题是我的活动侦听viewmodel字段更改但未调用回调!
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable observable, int i) {
Log.d(getClass().getSimpleName(), "changed");
}
});
User user = new User("user");
binding.setUser(user);
user.setName("newUser");
}
}
Run Code Online (Sandbox Code Playgroud)
和我的视图模型:
public class User extends BaseObservable {
public String name;
public User(String name) {
this.name = name;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
} …Run Code Online (Sandbox Code Playgroud) 我正在使用数据绑定,但遇到了一个问题,即我绑定到的视图属性在布局膨胀并且为绑定类设置视图模型后没有立即填充。
在包含 Fragment 中,我使用 BindingUtil 来膨胀 Fragment 的 onCreateView() 中的绑定布局。然后我立即设置绑定变量,这是我的视图模型。
但是,当我在设置绑定的视图模型后立即调试时,布局对于我绑定到视图模型的某些视图属性具有空值。如果我等待几分之一秒,属性将按预期通过绑定设置。
因此,视图属性的实际绑定何时发生?我认为它会在视图模型设置为绑定类后立即发生。这一定是错的...
有人可以帮助我用一种合理的方式来调试这个问题吗?
android android-layout android-fragments android-databinding
基本上我可以在 recyclerview adaper 上使用多行而没有任何问题,例如以下代码:
@Override
public ShowBookItemsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
switch (viewType) {
case 1:
layout = R.layout.item_heading_one;
break;
case 2:
layout = R.layout.item_heading_two;
break;
}
View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
ShowBookItemsViewHolder holder = new ShowBookItemsViewHolder(v);
return holder;
}
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试在使用 DataBinding 时使用此功能,但出现错误,但我不能这样做
这是我的错误代码:
@Override
public RobotViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
if (inflater == null) {
switch (viewType) {
case 0:
layout = R.layout.robot_item_action;
break;
case 1:
layout = …Run Code Online (Sandbox Code Playgroud) 这是我的数据绑定适配器:
@BindingAdapter("taskMinutes")
public static void taskMinutes(@NonNull TextView view, @NonNull Task task) {
if (task.getDueDate() == null) {
view.setText("");
return;
}
view.setText(String.valueOf(DateUtils.getDateMinutes(task.getDueDate())));
}
Run Code Online (Sandbox Code Playgroud)
并在xml:
app:taskMinutes="@{task}"
Run Code Online (Sandbox Code Playgroud)
分钟会EditText正常显示,但不会添加到 中task.dueDate。
但是如何添加适配器以将新输入从EditTextfiled添加到task.dueDate?
我正在尝试使用 android 数据绑定在 Kotlin 中设置一个带有 RecyclerView 的 Android 屏幕。我有一个包含片段的活动,该片段包含我使用数据绑定初始化的 RecyclerView。
问题是,当我尝试设置我的回收器视图的布局管理器时,应用程序抛出一个 IllegalStateException 抱怨指定的孩子(我假设这意味着 RecyclerView 或 LayoutManager)已经有一个父级,我需要运行 removeView( )。我尝试从 RecyclerView 中删除所有视图,但无济于事。
class HomeActivity : BaseActivity() {
private lateinit var mBinding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)
if(savedInstanceState != null){
return
}
val fragment = HomeFragment.newInstance()
supportFragmentManager.beginTransaction().add(R.id.home_fragment_container, fragment).commit()
}
}
Run Code Online (Sandbox Code Playgroud)
class HomeFragment : BaseFragment() {
private lateinit var mBinding: FragmentHomeBinding
private lateinit var mRecyclerView: RecyclerView
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? …Run Code Online (Sandbox Code Playgroud) android android-fragments kotlin android-recyclerview android-databinding
我决定在我的 Android 项目中使用 DataBinding 库。是否有任何插件/代码模板可用于安装到 Android Studio 中以使用 Android Studio 的向导自动生成的与 DataBinding 兼容的代码添加新的 Activity/Fragment 等?我每次都需要在 xml 中创建模型/演示者/变量,我可以让它们自动生成吗?
要包含的布局是这样的,child.xml:
<layout>
<data>
<variable
name="click"
type=""> <!-- What type should be here? -->
</data>
<LinearLayout>
<View onClick="@{click}"/>
</LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
要包含此内容,parent.xml:
<layout>
<data>
<variable
name="viewModel"
type="ViewModel"/>
</data>
<LinearLayout>
<View onClick="()->viewModel.click1()"/>
<include
bind:click="()->viewModel.click2()"/>
layout="@layout/child"/>
</LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
那么如何将 clickEvent 仅传递给 child.xml。由于不同的 parent.xml 具有不同的 ViewModel,我认为我不应该将 viewModel 传递给 child.xml。但我不知道如何将方法传递给 child.xml。
我现在正在做的解决方案是 Java 文件中的 setOnClickListener。我怀疑 dataBinding 是否可以使它更容易。
我是 Kotlin 的新手,这是我的问题:
我在我的应用程序中使用 dataBinding,当我想从布局设置我的变量时:
<?xml version="1.0" encoding="utf-8"?><layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="noteViewModel"
type="moeindeveloper.kotlinroomaac.ViewModel.NoteViewModel" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".View.MainActivity">
<ProgressBar
android:id="@+id/loading"
android:layout_width="48dp"
android:layout_height="48dp"
android:indeterminate="true"
android:visibility="@{noteViewModel.isLoading.get() ? View.VISIBLE : View.GONE}"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="@id/repository_rv"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@id/repository_rv"
app:layout_constraintTop_toTopOf="@id/repository_rv" />
<android.support.v7.widget.RecyclerView
android:id="@+id/repository_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminate="true"
android:visibility="@{noteViewModel.isLoading.get() ? View.GONE : View.VISIBLE}"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/row_item" />
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/addButton"
android:src="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.98"/>
</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
我的主要活动:
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
Run Code Online (Sandbox Code Playgroud)
创建时:
val viewModel:NoteViewModel = ViewModelProviders.of(this,viewModelFactory)
.get(NoteViewModel::class.java)
binding.noteViewModel …Run Code Online (Sandbox Code Playgroud) 我有一个 DataBinding 类ActivityMainBinding,其中 XML 看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<layout>
<android.support.design.widget.CoordinatorLayout 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/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/ic_add" />
</android.support.design.widget.CoordinatorLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
而 content_main.xml 是另一个绑定
<?xml version="1.0" encoding="utf-8"?>
<layout>
<android.support.constraint.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=".MainActivity"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
现在,在我的活动中,我设置了这样的内容视图。
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
Run Code Online (Sandbox Code Playgroud)
现在我可以使用此绑定访问所有 XML 元素。喜欢
Toolbar toolbar = activityMainBinding.toolbar;
Run Code Online (Sandbox Code Playgroud)
但我的一些小部件在包含的布局中 ContentMainBinding
现在,我如何ContentMainBinding从 …