Tôi nhận ra đây là một câu hỏi cũ, nhưng tôi muốn cung cấp một giải pháp để nó có thể giúp đỡ người khác với cùng một vấn đề. Điều này có thể đạt được bằng cách sử dụng chế độ xem hành động cho mục menu. Nó đòi hỏi một chút mã công bằng, nhưng đó là một cách tiếp cận sử dụng MVVM và có thể được sử dụng cho bất kỳ ràng buộc dữ liệu nào.
Đây là một ví dụ trong đó biểu tượng cho thấy một số thay đổi và nền nếu số lượng lớn hơn 0.
Xác định mục trình đơn
menu/main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_count"
android:enabled="true"
android:icon="@drawable/ic_menu_red_square"
android:title="@string/count"/>
</menu>
Xác định mô hình xem cho mục menu.
public class CountMenuViewModel extends BaseObservable {
@Bindable
int count;
public CountMenuViewModel() {}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
if (this.count < 0) {
this.count = 0;
}
notifyPropertyChanged(BR.count);
}
@Bindable({"count"})
public @DrawableRes int getBackground() {
if (count > 0) {
return R.drawable.ic_menu_blue_square;
}
return R.drawable.ic_menu_red_square;
}
@Bindable({"count"})
public String getCountText() {
if (count > 0) {
return String.valueOf(count);
}
return null;
}
}
Xác định cuộc gọi lại sẽ được thực hiện bởi hoạt động khi mục menu được nhấp.
public interface CountMenuActionCallback {
void onCountMenuItemClicked();
}
Tạo bố cục cho chế độ xem tác vụ. Bố cục sử dụng lớp mô hình chế độ xem và đặt văn bản cho số lượng và nền. Giao diện gọi lại được sử dụng cho OnClickListener cho chế độ xem hành động.
bố trí/menu_action_count.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.botnerd.samplesapp.CountMenuViewModel"
/>
<variable
name="callback"
type="com.botnerd.samplesapp.CountMenuActionCallback"
/>
</data>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> callback.onCountMenuItemClicked()}"
android:background="?android:attr/actionBarItemBackground">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="4dp"
android:src="@{data.background}"
tools:src="@drawable/ic_menu_red_square"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@{data.countText}"
tools:text="30"
android:textSize="14dp"
android:maxLines="1"
android:textColor="@android:color/white"
tools:ignore="SpUsage"/>
</FrameLayout>
</layout>
Lưu ý rằng một adapter tùy chỉnh ràng buộc được sử dụng cho thuộc tính android:src
. Đây là một bộ điều hợp tốt để thiết lập ImageView src thông qua ràng buộc dữ liệu.
@BindingAdapter({"android:src"})
public static void setSrc(ImageView view, @DrawableRes int resId) {
try {
view.setImageDrawable(ContextCompat.getDrawable(view.getContext(), resId));
} catch (Resources.NotFoundException e) {
}
}
Cuối cùng, tăng cấp độ và ràng buộc bố cục chế độ xem hành động trong hoạt động.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem menuItemCount = menu.findItem(R.id.action_count);
MenuActionCountBinding binding = MenuActionCountBinding.inflate(getLayoutInflater());
binding.setData(mCountMenuViewModel);
binding.setCallback(mCountMenuActionCallback);
MenuItemCompat.setActionView(menuItemCount, binding.getRoot());
MenuItemCompat.setShowAsAction(menuItemCount, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
return super.onCreateOptionsMenu(menu);
}
Để hoàn tất, dưới đây là tất cả các tệp trong mẫu không được xác định ở trên.
drawable/ic_menu_blue_square.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<padding android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp"/>
<solid android:color="#000080"/>
<corners android:radius="2dp"/>
</shape>
drawable/ic_menu_red_square.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<padding android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp"/>
<solid android:color="#800000"/>
<corners android:radius="2dp"/>
</shape>
bố trí/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<data>
<variable
name="callback"
type="com.botnerd.samplesapp.MainActivityActionCallback"
/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.botnerd.samplesapp.MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:onClick="@{() -> callback.onMinusClicked()}"
android:layout_marginStart="79dp"
app:layout_constraintBaseline_toBaselineOf="@+id/button2"
tools:layout_constraintBaseline_creator="1"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:onClick="@{() -> callback.onPlusClicked()}"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="25dp"
android:layout_marginTop="97dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/button"/>
</android.support.constraint.ConstraintLayout>
</layout>
MainActivityActionCallback.java
public interface MainActivityActionCallback {
void onPlusClicked();
void onMinusClicked();
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ActivityMainBinding mBinding;
CountMenuViewModel mCountMenuViewModel;
CountMenuActionCallback mCountMenuActionCallback = new CountMenuActionCallback() {
@Override
public void onCountMenuItemClicked() {
Toast.makeText(MainActivity.this, "Count clicked!", Toast.LENGTH_SHORT)
.show();
}
};
MainActivityActionCallback mActionCallback = new MainActivityActionCallback() {
@Override
public void onPlusClicked() {
mCountMenuViewModel.setCount(mCountMenuViewModel.getCount() + 1);
}
@Override
public void onMinusClicked() {
mCountMenuViewModel.setCount(mCountMenuViewModel.getCount() - 1);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCountMenuViewModel = new CountMenuViewModel();
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mBinding.setCallback(mActionCallback);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem menuItemCount = menu.findItem(R.id.action_count);
MenuActionCountBinding binding = MenuActionCountBinding.inflate(getLayoutInflater());
binding.setData(mCountMenuViewModel);
binding.setCallback(mCountMenuActionCallback);
MenuItemCompat.setActionView(menuItemCount, binding.getRoot());
MenuItemCompat.setShowAsAction(menuItemCount, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
return super.onCreateOptionsMenu(menu);
}
}
bạn có thể vui lòng thêm 'Fact' mã? –