当使用 DiffUtil ItemCallback 时,如何使用 DiffCallback 在 RecyclerView 中加载 newList。
当用户选择我希望 RecyclerView 更新的不同大小时,我想为用户提供从数据库返回不同大小列表的选项。
回收器视图适配器
RecyclerViewAdapter extends ListAdapter<WordEntity, RecyclerViewAdapter.ViewHolder> {
private RecyclerViewAdapter() {
super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<WordEntity> DIFF_CALLBACK = new DiffUtil.ItemCallback<WordEntiti>() {
@Override
public boolean areItemsTheSame...
@Override
public boolean areContentsTheSame...
};
@Override
public viewHolder onCreateViewHolder...
@Override
public void onVindViewHolder ...
class ViewHolder extends RecyclerView.ViewHolder ...
public void updateWordList(List<WordEntity> words) {
final WordDiffCallBack diffCallBack = new WordDiffCallBack(list???, words);
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack);
this.list???.clear();
this.addAll(words);
diffResult.dispatcheUpdatesTo(this);
}
Run Code Online (Sandbox Code Playgroud)
WordsDiffCallBack
private final List<WordEntity> …Run Code Online (Sandbox Code Playgroud) 我已经建立了一个包含 3 列(标题、描述、流派)的房间数据库。我想用用户指定的流派(喜剧、恐怖等)查询流派列并返回结果。
我希望查询只检索流派与用户选择的流派相匹配的条目。
@Dao
public interface MovieDAO {
@Query SELECT * FROM movie_table WHERE genre")
pubic LiveData<List<Movie>> getAllMovies();
}
Run Code Online (Sandbox Code Playgroud)
在 Repository.class 中,我可以通过这种方式将用户选择的流派字符串传递给 Query 吗?
public class MovieRepository {
private MovieDao movieDao;
private LiveData<List<Movie>> allMovies;
public MovieRepository(Application application) {
MovieDatabase database = MovieDatabase.getInstance(application);
movieDao = database.MovieDao();
allMovies = movieDao.getAllMovies
}
public void findMoviesByGenre(String genre) {
movieDao.findMoviesByGenre(genre);
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定我是否在 findMovieByGenre() 方法中遗漏了什么
public class MovieViewModel exteneds AndroidViewModel {
private MovieRepository repository;
private LiveData<List<Movie>> allMovies
// Constructor,
public MovieViewModel(@NonNull …Run Code Online (Sandbox Code Playgroud) 我正在存储一个 PNG 文件,该文件被转换为位图,该位图被转换为 Byte[] 并存储 MySQL 数据库。
当我尝试调用数据库中的项目时,出现以下错误。
E/SQLiteQuery:异常:行太大,无法放入 CursorWindow requiredPos=0,totalRows=1;查询:SELECT * FROM myTable
引起原因:android.database.sqlite.SQLiteBlobTooBigException:行太大,无法放入 CursorWindow requiredPos=0,totalRows=1
有没有办法增加光标窗口的大小以接受 byte[]?
@Dao
public interface MyDAO {
@Query("SELECT * FROM myTable")
LiveData<List<MyEntity>>getAllImages();
Run Code Online (Sandbox Code Playgroud)
public class MyRepository {
private MyDAO mMyDao;
private LiveData<List<MyEntity>> mList;
public MyRepository(Application application) {
MyDatabase db = MyDatabase.getInstance(application);
this.mMyDao = db.mMyDao();
mList = mMyDao.getAllImages();
}
public LiveData<List<MyEntity>> getAllImages(){
return mList;
}
Run Code Online (Sandbox Code Playgroud)
import java.util.List;
public class MainViewModel extends AndroidViewModel {
private MyRepository mRepository;
private LiveData<List<MyEntity>> mList;
public MainViewModel(Application application) {
super(application);
mRepository …Run Code Online (Sandbox Code Playgroud) 我想在同一个活动中使用 ViewBinding 和 DataBinding。如果这是可能的,您将如何在活动中实施它?
这是我到目前为止所尝试过的,
@Override
protected void onCreate(Bundle savedInstanceState) {
ActivityMainBinding viewBinding = ActivityMainBinding.inflate(getLayoutInflater();
View view = viewBinding.getRoot();
setContentView(view)
ActivityMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的 RecyclerView 上运行单元测试。对于我的第一个测试,我想看看 RecyclerView 是否显示。
@RunWith(RobolectricTestRunner::class)
class WordListFragmentTest {
// Executes task sin the Architecture component in the same thread.
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
private lateinit var scenario: FragmentScenario<WordListFragment>
private lateinit var viewModel: MainViewModel
val word = Word("Word")
@Before
fun setup() {
viewModel = mock(MainViewModel::class.java)
scenario = launchFragment(
factory = MainFragmentFactory(viewModel),
fragmentArgs = null,
themeResId = R.style.Theme_Words,
initialState = Lifecycle.State.RESUMED
)
}
@Test
fun `recyclerView displayed`() {
onView(withId(R.id.recyclerView))
.check(matches(isDisplayed()))
}
Run Code Online (Sandbox Code Playgroud)
运行测试后我收到以下错误。
java.lang.Exception: Main looper has queued unexecuted runnables. This …Run Code Online (Sandbox Code Playgroud) android robolectric android-recyclerview android-unit-testing
我正在尝试为 DialogFragment 创建一个独立的单元测试,以便 DialogFragment 可以单独进行测试。我正在使用 FragmentScenario 启动 DialogFragment,现在我正在尝试确认是否显示对话框消息,但最终我将测试按钮单击。
class ResetScoreDialog (val viewModel: MyViewModel) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(it)
builder.setMessage(getString(R.string.resetscore_dialog_message))
.setPositiveButton(getString(R.string.confirm),
DialogInterface.OnClickListener { dialog, id ->
viewModel.resetScore()
})
// Create the AlertDialog object and return it
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试
@RunWith(RobolectricTestRunner::class)
class ResetScoreDialogTest {
private lateinit var scenario: FragmentScenario<ResetScoreDialog>
private lateinit var viewModel: MyViewModel …Run Code Online (Sandbox Code Playgroud) android android-dialog android-dialogfragment android-espresso
如何从应用程序内的设置选项以编程方式关闭通知?
在 Preference 更改侦听器的 if 语句中创建 Notification 通道的方法似乎正在完成这项工作。我担心我现在正在创建多个通知渠道。
首选项.xml
<PreferenceCategory
app:key="notification_category"
app:title="Notification"
<SwitchPreferenceCompat
app:key="notification_state"
app:title="Enable notification message"/>
</PrefenceCategory>
Run Code Online (Sandbox Code Playgroud)
主Activity.class
boolean mNotificationState;
Notification mNotification;
SharedPreferences.OnSharedPreferenceChangeListener listener;
@Override
protected void onCreate(Bundle saveInstanceState) {
...
// Create notification object.
mNotification = Notification(this);
// Prefernce Listener
listner = (sharedPrefences, s) -> {
mNotificationState = SharedPreferences.getBoolean("notification_state", true);
if(mNotificationState) {
// concerned that a memory leak migh occur.
notification.createNotificationChannel();
} else {
notification.getNotificationManager().cancelAll();
}
}
/**
* registerOnSharedPreferenceChangeListener
*/
@Override
public void onResume() {
super.onResume();
PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext()).registerOnSharedPreferenceChangeListener(listener); …Run Code Online (Sandbox Code Playgroud) 在具有多个主题的应用程序中,如何从样式文件更改 CardView 的背景颜色?
样式文件
<style name="AppTheme1" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimaryTheme1</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkTheme1</item>
<item name="colorAccent">@color/colorAccentTheme1</item>
</style>
<style name="AppTheme2" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimaryTheme2</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkTheme2</item>
<item name="colorAccent">@color/colorAccentTheme2</item>
</style>
<style name="AppTheme3" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimaryTheme3</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkTheme3</item>
<item name="colorAccent">@color/colorAccentTheme3</item>
</style>
Run Code Online (Sandbox Code Playgroud)
卡片视图
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:elevation="4dp"
app:cardCornerRadius="15dp">
Run Code Online (Sandbox Code Playgroud)
我想更改每个主题的背景颜色,我希望在styles.xml 文件中完成此操作。
当我更改模拟器或手机上的方向时,片段会额外加载一次。如果我将设备旋转 3 次,则片段将在最后一次旋转后加载 3 次;如果我将设备旋转 5 次,则片段将在最后一次旋转后加载 5 次。
主要活动
...
FragmentOne fragment = new FragmentOne();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.main_container, fragmnet);
transaction.commit();
Run Code Online (Sandbox Code Playgroud)
我在片段中唯一拥有的就是日志,没有任何东西会导致片段多次加载。片段一
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.d(TAG, "onCreateView: ");
return inflater.inflate(R.layout.fragment_fragment_one, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onViewCreated: ");
}
Run Code Online (Sandbox Code Playgroud)
这是一次旋转后的日志副本,请注意 onCreateView 在一次方向更改时被多次调用。
2020-04-13 01:23:07.396 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.396 10857-10857/com.example.myapplication …Run Code Online (Sandbox Code Playgroud)