我正在使用android数据绑定,以下是我用来设置Variable
的类public class DayTemp extends BaseObservable implements Serializable {
@SerializedName("dt")
long date;
@SerializedName("pressure")
double pressure;
@SerializedName("humidity")
long humidity;
@SerializedName("temp")
Temp temp;
@SerializedName("weather")
ArrayList<Weather> weathers;
@SerializedName("speed")
double speed;
@SerializedName("deg")
double deg;
@SerializedName("clouds")
double clouds;
@Bindable
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
notifyPropertyChanged(BR.date);
}
@Bindable
public double getPressure() {
return pressure;
}
public void setPressure(double pressure) {
this.pressure = pressure;
notifyPropertyChanged(BR.pressure);
}
@Bindable
public long getHumidity() {
return humidity;
}
public void setHumidity(long humidity) {
this.humidity = humidity;
notifyPropertyChanged(BR.humidity);
}
@Bindable
public Temp getTemp() {
return temp;
}
public void setTemp(Temp temp) {
this.temp = temp;
notifyPropertyChanged(BR.temp);
}
@Bindable
public ArrayList<Weather> getWeathers() {
return weathers;
}
public void setWeathers(ArrayList<Weather> weathers) {
this.weathers = weathers;
notifyPropertyChanged(BR.weathers);
}
@Bindable
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
notifyPropertyChanged(BR.speed);
}
@Bindable
public double getDeg() {
return deg;
}
public void setDeg(double deg) {
this.deg = deg;
notifyPropertyChanged(BR.deg);
}
@Bindable
public double getClouds() {
return clouds;
}
public void setClouds(double clouds) {
this.clouds = clouds;
notifyPropertyChanged(BR.clouds);
}
}
在这个POJO课程中,我可以将所有值设置为我的recyclerview bt,我无法访问天气学家的arraylist,也无法获得与之相关的字段。
public class Weather extends BaseObservable implements Serializable {
@SerializedName("id")
long id;
@SerializedName("main")
String main;
@SerializedName("description")
String desc;
@SerializedName("icon")
String icon;
@Bindable
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
notifyPropertyChanged(BR.id);
}
@Bindable
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
notifyPropertyChanged(BR.main);
}
@Bindable
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
notifyPropertyChanged(BR.desc);
}
@Bindable
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
notifyPropertyChanged(BR.icon);
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
>
<data>
<import type="com.weatherappforleftshift.currentlocation.DateUtils"/>
<variable
name="daytemp" type="com.weatherappforleftshift.currentlocation.model.DayTemp"/>
</data>
<TextView
android:id="@+id/weather_status"
android:layout_width="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:text="@{HOW TO SET TEXT HERE FROM weathers list}"
android:layout_height="wrap_content" />
</layout>
我想将天气等级的Icon和Description设置为我的Recyclerview。
如何在项目布局中实现这一点????
答案 0 :(得分:0)
你可以看看这个github项目
https://github.com/arunshankar87/triptrial
我已经处理了recyclerview的数据绑定
更具体地说,以下2个文件将是您感兴趣的
https://github.com/arunshankar87/triptrial/blob/master/app/src/main/res/layout/row_layout.xml
答案 1 :(得分:0)
添加您的虚拟机:
@Bindable
public String getWeathersText() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < weathers.size(); i++) {
builder.append(weathers.get(i).getText);
}
return builder.toString();
}
并在你的布局xml:
<TextView
android:id="@+id/weather_status"
android:layout_width="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
app:weathersText="@{daytemp.weathersText}"
android:layout_height="wrap_content" />
我没有检查过,但我认为它应该有帮助...
答案 2 :(得分:0)
首先,您需要创建&#34;天气&#34;的变量/实例。布局xml中的类。
<variable
name="weatherData" type="<packageName>.Weather"/>
你可以使用这个&#34; weatherData&#34;对象检索任何&#34;天气&#34;类属性
您只需要将来自RecyclerViewAdapter类的天气对象传递给xml。
bindind.setWeatherData(whetherList.get(position));
答案 3 :(得分:0)
有很多方法可以给这只猫蒙皮。但是您专门讲的是Binding,所以让我们以正确的方式进行:)。
您将需要一些东西,但请不要担心,其中大部分是一次性的样板,您可以在每个recyclerview中反复使用。那就是它的美。
1)布局中的RecyclerView
2)RecyclerView的通用绑定适配器
3)JMVStatic适配器,用于转换类型和设置
4)用于与RecyclerView的适配器通信的接口
差不多了,所以让我们进入代码。 顺便说一句,如果您不了解它,可以进行几乎所有的复制和粘贴,尽管它可能会做更多您需要的事情。另外,还有其他方法可以处理点击事件。您可以自己将它们嵌套到行布局文件中。
步骤1: 接口类
interface IBindingRecyclerView<T> {
/////////////////////////////////////////////////////////////////
// EXTERNAL METHODS
/////////////////////////////////////////////////////////////////
fun getRowLayoutResourceId(): Int
fun getBindingModelId(): Int
fun getActionButtonResourceId(): Int
fun onItemClick(model: T, position: Int)
fun onItemLongClick(model: T, position: Int)
fun onActionItemClick(model: T, position: Int, holder: BindingRecyclerViewAdapter.BindingHolder)
}
请注意*,您可能会或可能不会在乎点击处理程序,长按或操作项。一个动作项将是一个子按钮,不被认为是单击行。
步骤2: JVM静态绑定适配器
object BindingAdapterMethods {
/////////////////////////////////////////////////////////////////
// MEMBERS
/////////////////////////////////////////////////////////////////
private var TAG: String = SSGlobals.SEARCH_STRING + "BindingAdapterMethods"
/////////////////////////////////////////////////////////////////
// METHODS
/////////////////////////////////////////////////////////////////
/**
* This makes sure that the interface and observable list is set in the recyclerView's adapter. If the adapter is null,
* then a new one is created.
* @param view
* @param iBindingRecyclerView
* @param list
*/
@JvmStatic
@BindingAdapter(value = ["bindRcvInterface", "bindRcvList", "bindRcvPlusInterface"], requireAll = false)
fun setBindingRecyclerViewProperties(view: RecyclerView, iBindingRecyclerView: IBindingRecyclerView<*>, list: ObservableArrayList<*>?, iBindingRecyclerViewPlus: IBindingRecyclerViewPlus<*>? = null) {
if (view.adapter == null) {
val layoutManager = LinearLayoutManager(view.context)
view.layoutManager = layoutManager
view.invalidateItemDecorations()
view.addItemDecoration(VerticalItemDecoration(0))
view.adapter = BindingRecyclerViewAdapter<Any?>()
}
val adapter = view.adapter as BindingRecyclerViewAdapter<*>
adapter.setIBindingRecyclerView(iBindingRecyclerView, iBindingRecyclerViewPlus)
if(list != null) {
adapter.setList(list)
}
}
}
注意*这是简化的,仅添加一个适配器,随着绑定使用的增加,您将有很多。您可以忽略recyclerViewPlus参数,只需删除它即可。我将其用于布局的高度自定义,并将更多数据设置到行ui的子ui中,因为您知道数据绑定需要您遍历树。但是我离题了。
步骤3: 实施活动或分段
class MyListFragment : BaseFragment(), IBindingRecyclerView<YourListModelType> {
/////////////////////////////////////////////////////////////////
// MEMBERS
/////////////////////////////////////////////////////////////////
private lateinit var mBinding: FragmentYourItemListBinding
private var mYourItemModelList : ObservableArrayList<YourListModelType> = ObservableArrayList()
/////////////////////////////////////////////////////////////////
// LIFE CYCLE OVERRIDES
/////////////////////////////////////////////////////////////////
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_your_item_list, container, false)
mBinding.fragment = this
mBinding.iBindingRecyclerView = this
return mBinding.root
}
override fun onResume() {
super.onResume()
fillYourListOfItems()
}
/////////////////////////////////////////////////////////////////
// PROPERTIES
/////////////////////////////////////////////////////////////////
fun getYourListItemModelList() : ObservableArrayList<YourListItemModelType> {
return mYourItemModelList
}
/////////////////////////////////////////////////////////////////
// IBINDINGRECYCLERVIEW OVERRIDES
/////////////////////////////////////////////////////////////////
override fun getRowLayoutResourceId(): Int {
return R.layout.row_your_layout_file
}
override fun getBindingModelId(): Int {
return BR.YourListModelType //defined in the xml coming up next
}
override fun getActionButtonResourceId(): Int {
return -1 //if you aren't using, just return -1 or remove from interface
}
override fun onItemClick(model: YourListModelType, position: Int) {
//handle the click of your item, launch a detail activity, whatever you need
}
override fun onItemLongClick(model: YourListModelType, position: Int) {
//same as above, but if not using, you can remove from interface
}
override fun onActionItemClick(model: YourListModelType, position: Int, holder: BindingRecyclerViewAdapter.BindingHolder) {
//if not using, you can remove from interface
}
}
好,所有的设置都就位了,现在是简单的部分。 xml绑定。 :) 首先在顶部声明变量。
第4步可变声明
<data>
<variable name="fragment" type="com.yourpath.fragments.MyListFragment" />
<variable name="iBindingRecyclerView" type="com.yourpath.interfaces.IBindingRecyclerView"/>
</data>
对于所有回收者视图,始终无处不在地继续使用通用。
适用于大多数情况的第5步通用适配器(复制粘贴保持原样)
您可以删除不使用的接口回调。
class BindingRecyclerViewAdapter<T> : RecyclerView.Adapter<BindingRecyclerViewAdapter.BindingHolder>(), View.OnClickListener, View.OnLongClickListener {
/////////////////////////////////////////////////////////////////
// MEMBERS
/////////////////////////////////////////////////////////////////
private val MODEL_TAG = -124
private val MODEL_POSITION_TAG = -125
private var mRowLayoutResourceId: Int = 0
private var mBindingModelId: Int = 0
private var mActionButtonId: Int = 0
private var mHasActionButton: Boolean = false
private var mList: ObservableArrayList<*>? = null
private lateinit var mIBindingRecyclerView: IBindingRecyclerView<T>
private var mIBindingRecyclerViewPlus: IBindingRecyclerViewPlus<T>? = null
/////////////////////////////////////////////////////////////////
// PROPERTIES
/////////////////////////////////////////////////////////////////
/**
* This is now how the interface needs to be set. This is taken care of in the @BindingAdapter
* method "bind:rcvInterface" (BindingAdapterMethods). I also decided to take care of setting the
* rowLayoutResourceId here, more as a "might as well" sort of thing, but also preventing the chance
* of a null ref exception if we were to use mIBindingRecyclerView.getRowLayoutResourceId() and
* mIBindingRecyclerView was null. Same goes for bindingModelId.
* @param iBindingRecyclerView
*/
fun setIBindingRecyclerView(iBindingRecyclerView: IBindingRecyclerView<*>, iBindingRecyclerViewPlus: IBindingRecyclerViewPlus<*>? = null) {
mIBindingRecyclerView = iBindingRecyclerView as IBindingRecyclerView<T>
mRowLayoutResourceId = iBindingRecyclerView.getRowLayoutResourceId()
mBindingModelId = iBindingRecyclerView.getBindingModelId()
mActionButtonId = iBindingRecyclerView.getActionButtonResourceId()
mHasActionButton = mActionButtonId > 0
mIBindingRecyclerViewPlus = iBindingRecyclerViewPlus as IBindingRecyclerViewPlus<T>?
}
/**
* This is how the list is set and any changes made will be notified here. If notifyDataSetChanged()
* is not called here, then the view will not be updated with the list changes. Setting the list gets
* taken care of in the @BindingAdapter method "bind:rcvList" (BindingAdapterMethods). Anytime the list
* changes in the activity/fragment, it will trigger the "bind:rcvList" method, and that will call
* setList(), thus updating the list and notifying data set changed which updates the view properly.
* @param list
*/
fun setList(list: ObservableArrayList<*>) {
mList = list
notifyDataSetChanged()
}
/////////////////////////////////////////////////////////////////
// BASE CLASS OVERRIDES
/////////////////////////////////////////////////////////////////
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingHolder {
val inflater = LayoutInflater.from(parent.context)
val viewDataBinding = DataBindingUtil.inflate<ViewDataBinding>(inflater, mRowLayoutResourceId, parent, false)
return BindingHolder(viewDataBinding)
}
override fun onBindViewHolder(holder: BindingHolder, position: Int) {
val model = mList!![position]
holder.binding.setVariable(mBindingModelId, model)
holder.binding.root.setTag(MODEL_TAG, model)
holder.binding.root.setTag(MODEL_POSITION_TAG, position)
holder.binding.root.setOnClickListener(this)
holder.binding.root.setOnLongClickListener(this)
if(mIBindingRecyclerViewPlus != null){
mIBindingRecyclerViewPlus?.onRowBinding(model as T, position, holder)
}
if (mHasActionButton) {
val btnAction = holder.binding.root.findViewById<View>(mActionButtonId)
btnAction.setTag(MODEL_TAG, model)
btnAction.setTag(MODEL_POSITION_TAG, position)
onActionClick(btnAction, holder)
}
holder.binding.executePendingBindings()
}
override fun getItemCount(): Int {
return if (mList == null) 0 else mList!!.size
}
////////////////////////////////////////////////////////////////
// CLICK LISTENERS
////////////////////////////////////////////////////////////////
override fun onClick(v: View) {
val model = v.getTag(MODEL_TAG) as T
val position = v.getTag(MODEL_POSITION_TAG) as Int
mIBindingRecyclerView.onItemClick(model, position)
}
override fun onLongClick(v: View): Boolean {
val model = v.getTag(MODEL_TAG) as T
val position = v.getTag(MODEL_POSITION_TAG) as Int
mIBindingRecyclerView.onItemLongClick(model, position)
return true
}
fun onActionClick(btnAction: View, holder: BindingHolder) {
btnAction.setOnClickListener {
val model = btnAction.getTag(MODEL_TAG) as T
val position = btnAction.getTag(MODEL_POSITION_TAG) as Int
mIBindingRecyclerView.onActionItemClick(model, position, holder)
}
}
////////////////////////////////////////////////////////////////
// SCOPED CLASSES
////////////////////////////////////////////////////////////////
class BindingHolder(var binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root)
}
最后一步 使用它:)。
第6步绑定您的回收站视图
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingStart="@dimen/dp_20"
android:paddingEnd="@dimen/dp_20"
app:bindRcvInterface="@{iBindingRecyclerView}"
app:bindRcvList="@{fragment.getYourListItemModelList}"/>
注意*,您无需指定()符号,只需如上所示使用它即可。
所以,好消息是,这大部分是一次性设置。也可以在您的应用中使用它。
OH YEAH和Optional,它在我的代码中,但可能会做您自己的变体,以处理回收站视图的外观。
垂直装饰器
class VerticalItemDecoration (private var spacingInPx: Int) : RecyclerView.ItemDecoration() {
/*///////////////////////////////////////////////////////////////
// ITEM DECORATION OVERRIDES
*////////////////////////////////////////////////////////////////
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
outRect.bottom = spacingInPx
}
}
可重复使用的物品包括:
所以实际上您只是在实现接口,以可观察列表的形式提供列表,在onCreate中设置变量,并将两行放在xml中并重复:)。
快乐编码。希望这会有所帮助。