小编Sha*_*awn的帖子

如何使用 DiffUtils 更新 RecyclerView 中的列表?

当使用 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)

android android-recyclerview android-diffutils

7
推荐指数
2
解决办法
6434
查看次数

在 Android Room 如何创建和调用自定义查询

我已经建立了一个包含 3 列(标题、描述、流派)的房间数据库。我想用用户指定的流派(喜剧、恐怖等)查询流派列并返回结果。

DAO接口

我希望查询只检索流派与用户选择的流派相匹配的条目。

@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)

sql android mvvm viewmodel android-room

6
推荐指数
1
解决办法
3239
查看次数

行太大,无法放入光标窗口

我正在存储一个 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)

sql android

5
推荐指数
0
解决办法
6898
查看次数

可以在同一个活动中使用 dataBinding 和 ViewBinding 吗?

我想在同一个活动中使用 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)

android android-databinding android-viewbinding

5
推荐指数
1
解决办法
4450
查看次数

主 Looper 将未执行的可运行对象排队

我正在尝试在我的 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

5
推荐指数
0
解决办法
2743
查看次数

如何在对话框片段上运行单元测试?

我正在尝试为 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

3
推荐指数
1
解决办法
1725
查看次数

如何从应用程序内部关闭应用程序通知

如何从应用程序内的设置选项以编程方式关闭通知?

在 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)

android android-preferences android-notifications

2
推荐指数
1
解决办法
3306
查看次数

如何从主题更改 CardView 背景颜色

在具有多个主题的应用程序中,如何从样式文件更改 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 文件中完成此操作。

android android-xml android-styles android-cardview

1
推荐指数
1
解决办法
1965
查看次数

方向改变时片段加载多次

当我更改模拟器或手机上的方向时,片段会额外加载一次。如果我将设备旋转 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)

android screen-orientation android-fragments

1
推荐指数
1
解决办法
1624
查看次数