Android studio 带有定制RecycleServiceUrsorAdapter的RecycleyView非常滞后/缓慢

Android studio 带有定制RecycleServiceUrsorAdapter的RecycleyView非常滞后/缓慢,android-studio,android-recyclerview,android-cursorloader,horizontal-recyclerview,Android Studio,Android Recyclerview,Android Cursorloader,Horizontal Recyclerview,我正在使用一个自定义的RecycleServiceUrsorAdapter,它是我从一篇文章中复制的。我用它成功地构建了我的应用程序,但是,每当我滚动时,它都非常慢。 我对此做了很多研究,找到了很多解决方案,但似乎没有一个有效。 我决定使用listView,所以我使用了CursorAdapter,情况更糟。 我使用了一个自定义的布局管理器,但没有任何更改。 拜托,我不知道该怎么办了。有人知道这是什么原因吗 活动 MyViewHolder 公共类cardViewHolder扩展了RecyclerV

我正在使用一个自定义的RecycleServiceUrsorAdapter,它是我从一篇文章中复制的。我用它成功地构建了我的应用程序,但是,每当我滚动时,它都非常慢。 我对此做了很多研究,找到了很多解决方案,但似乎没有一个有效。 我决定使用listView,所以我使用了CursorAdapter,情况更糟。 我使用了一个自定义的布局管理器,但没有任何更改。 拜托,我不知道该怎么办了。有人知道这是什么原因吗

活动 MyViewHolder
公共类cardViewHolder扩展了RecyclerView.ViewHolder{
公共文本视图术语视图,定义视图;
公共图像按钮添加按钮、关闭按钮、旋转按钮、旋转按钮2、添加按钮2;
公共图像视图前视图、后视图;
公共视图前卡视图、后卡视图;
公共字符串术语;
公共字符串定义;
@RequiresApi(api=Build.VERSION\u CODES.O)
公共cardViewHolder(@NonNull View itemView){
超级(项目视图);
}
@RequiresApi(api=Build.VERSION\u CODES.O)
公共void setData(光标){
int-idColumnIndex=cursor.getColumnIndexOrThrow(FlashContract.CardEntry.\u-ID);
int setIDColumnIndex=cursor.getColumnIndexOrThrow(FlashContract.CardEntry.CARD\u SET\u ID);
int termColumnIndex=cursor.getColumnIndexOrThrow(FlashContract.CardEntry.COLUMN_TERM);
int definitionColumnIndex=cursor.getColumnIndexOrThrow(FlashContract.CardEntry.COLUMN_定义);
_ID=cursor.getLong(idColumnIndex);
字符串setId=cursor.getString(setIDColumnIndex);
String term=cursor.getString(termColumnIndex);
字符串定义=cursor.getString(definitionColumnIndex);
表_ID=setId;
if(IsWellFormedUri(任期)){
frontView.setVisibility(视图.可见);
termView.setVisibility(View.GONE);
毕加索.get().load(term).fit().into(frontView);
}否则{
if(术语长度()
public class FlashCardActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
    ListView listView;
    String SET_ID;
    int CARD_LOADER_ID = 0;
    Uri currentSetUri;
    FloatingActionButton addNewCard, userStats, openFullScreen;
    FlashCardCursorAdapter cardCursorAdapter;
    RecyclerView recyclerView;
    FlashcardRecyclerViewAdapter recyclerViewAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flash_card);

        //loadViews from the xml layout
        loadViews();

        //initialize the listview
//        initListView();

        // initialize the recycerView
        initRecyclerView();

        //get the data from the setActivity
        getDataFromIntent();

        recyclerView.smoothScrollToPosition(0);

        //create new card
        addNewCard.setOnClickListener(v -> {
            setAddNewCard();
            recyclerView.smoothScrollToPosition(recyclerViewAdapter.getItemCount());
//            listView.smoothScrollToPosition(cardCursorAdapter.getCount());
        });

        getSupportLoaderManager().initLoader(CARD_LOADER_ID,null,this);
    }

    private void loadViews(){
        recyclerView = findViewById(R.id.recycler);
        listView = findViewById(R.id.CardListView);
        addNewCard = findViewById(R.id.add);
        userStats = findViewById(R.id.stats);
        openFullScreen = findViewById(R.id.fullscreen);
    }

    void initListView(){
        cardCursorAdapter = new FlashCardCursorAdapter(this,null);
        listView.setAdapter(cardCursorAdapter);
        listView.smoothScrollToPosition(cardCursorAdapter.getCount());
    }

    void initRecyclerView(){
        recyclerViewAdapter = new FlashcardRecyclerViewAdapter(this,null);
        recyclerViewAdapter.setHasStableIds(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,true);
        PreCachingLayoutManager preCachingLayoutManager = new PreCachingLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(preCachingLayoutManager);
        recyclerView.setAdapter(recyclerViewAdapter);
    }

    void setAddNewCard (){
        long time = Calendar.getInstance().getTimeInMillis();
        String term = getString(R.string.example_front_text);
        String definition = getString(R.string.example_back_text);
        ContentValues contentValues  = new ContentValues();
        contentValues.put(FlashContract.CardEntry.CARD_SET_ID,SET_ID);
        contentValues.put(FlashContract.CardEntry.COLUMN_TERM,term);
        contentValues.put(FlashContract.CardEntry.COLUMN_DEFINITION,definition);
        contentValues.put(FlashContract.CardEntry.COLUMN_DATE_CREATED,time);
        Uri rowAdded = getContentResolver().insert(FlashContract.CardEntry.CONTENT_URI,contentValues);
        if(rowAdded != null){
            Log.d("FlashCardListActivity", "inserted "+rowAdded);
        }else {
            Log.d("FlashCardListActivity", "insert Failed "+rowAdded);

        }
        recyclerViewAdapter.notifyDataSetChanged();
//        cardCursorAdapter.notifyDataSetChanged();
    }

    void getDataFromIntent(){
        final Intent intent = getIntent();
        currentSetUri = intent.getData();
        SET_ID = intent.getExtras().getString("set_id");
        FlashContract.CardEntry.TABLE_NAME = SET_ID;

    }


    @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {

        String[] projection = {
                FlashContract.CardEntry._ID,
                FlashContract.CardEntry.COLUMN_DATE_CREATED,
                FlashContract.CardEntry.CARD_SET_ID,
                FlashContract.CardEntry.COLUMN_IMAGE_AVAILABLE,
                FlashContract.CardEntry.COLUMN_URI,
                FlashContract.CardEntry.COLUMN_DEFINITION,
                FlashContract.CardEntry.COLUMN_TAG,
                FlashContract.CardEntry.COLUMN_TERM,
                FlashContract.CardEntry.COLUMN_FRIDAY,
                FlashContract.CardEntry.COLUMN_MONDAY,
                FlashContract.CardEntry.COLUMN_SATURDAY,
                FlashContract.CardEntry.COLUMN_SUNDAY,
                FlashContract.CardEntry.COLUMN_THURSDAY,
                FlashContract.CardEntry.COLUMN_TUESDAY,
                FlashContract.CardEntry.COLUMN_WEDNESDAY
        };
        return new CursorLoader(this, FlashContract.CardEntry.CONTENT_URI,projection,null,null,null);
    }

    @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
//        cardCursorAdapter.swapCursor(data);
        recyclerViewAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {
        recyclerViewAdapter.swapCursor(null);
//        cardCursorAdapter.swapCursor(null);
    }
}
public abstract class CursorRecyclerViewAdapter <ViewHolder extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<ViewHolder> {
    private DataSetObserver dataSetObserver;
    private boolean dataValid;
    private int rowIdColumn;
    private Context context;
    private Cursor mCursor;

    public CursorRecyclerViewAdapter(Context context , Cursor cursor){
        this.context = context;
        this.mCursor = cursor;
        dataValid = cursor != null;
        rowIdColumn = dataValid? cursor.getColumnIndexOrThrow(FlashContract.CardEntry._ID) : -1;
        dataSetObserver = new NotifyingDataSetObserver(this);
        if(cursor != null){
            cursor.registerDataSetObserver(dataSetObserver);
        }
    }

    public Cursor getmCursor(){
        return mCursor;
    }

    @Override
    public long getItemId(int position) {
        if(dataValid && mCursor != null && mCursor.moveToPosition(position))
            return mCursor.getLong(rowIdColumn);
        return 0;
    }

    @Override
    public int getItemCount() {
        if(dataValid && mCursor != null) return mCursor.getCount();

        return 0;
    }

    @Override
    public void setHasStableIds(boolean hasStableIds) {
        super.setHasStableIds(true);
    }

    public static final String TAG = FlashCardCursorAdapter2.class.getSimpleName();
    public abstract void onBindViewHolder(ViewHolder holder, Cursor cursor1);

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        if(!dataValid){
            throw new IllegalStateException("The cursor is invalid, Cannot call method");
        }

        if(!mCursor.moveToPosition(position)){throw new IllegalStateException(" Cannot move cursor to position "+position);
        }
        onBindViewHolder(holder, mCursor);
    }

    public void changeCursor(Cursor cursor){
        Cursor oldCursor = swapCursor(cursor);
        if(oldCursor != null) oldCursor.close();
    }

    public Cursor swapCursor(Cursor cursor){
        if(cursor == null){
            return null;
        }
        final Cursor oldCursor = mCursor;
        if(oldCursor != null && dataSetObserver != null){
            oldCursor.unregisterDataSetObserver(dataSetObserver);
        }

        mCursor = cursor;
        if(mCursor != null){
            if(dataSetObserver != null){
                mCursor.registerDataSetObserver(dataSetObserver);
            }
        rowIdColumn = cursor.getColumnIndexOrThrow("_id");
        dataValid = true;
        }else {rowIdColumn = -1;
        dataValid = false ;
        }
        notifyDataSetChanged();

        return oldCursor;
    }

    public void setDataValid(boolean dataValid) {
        this.dataValid = dataValid;
    }


    private class NotifyingDataSetObserver extends DataSetObserver {
        private RecyclerView.Adapter adapter;

        public NotifyingDataSetObserver(RecyclerView.Adapter adapter) {
            this.adapter = adapter;
        }

        @Override
        public void onChanged() {
            super.onChanged();
            ((CursorRecyclerViewAdapter) adapter).setDataValid(true);
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            ((CursorRecyclerViewAdapter) adapter).setDataValid(false);
            adapter.notifyDataSetChanged();
        }
    }
}
public class FlashcardRecyclerViewAdapter extends CursorRecyclerViewAdapter{
    public static Context context;
    public static String TABLE_ID = "";
    public Cursor cursor;
    static AnimatorSet rightOut;
    static AnimatorSet  leftIn;
    public String term;
    public String definition;


    public static long _ID;
    public static boolean isBackVisible = false;
    public static boolean isFront = true;

    public FlashcardRecyclerViewAdapter(Context context, Cursor cursor) {
        super(context, cursor);
        this.context = context;
    }



    @RequiresApi(api = Build.VERSION_CODES.O)
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).inflate(R.layout.card_view_list_item,parent,false);
        cardViewHolder holder = new cardViewHolder(itemView);
        holder.termView = itemView.findViewById(R.id.term);
        holder.definitionView = itemView.findViewById(R.id.definition_text_field);
        holder.addButton = itemView.findViewById(R.id.edit_front);
        holder.addButton2 = itemView.findViewById(R.id.edit2_front);
        holder.closeButton = itemView.findViewById(R.id.remove_card);
        holder.rotateButton = itemView.findViewById(R.id.rotate_card);
        holder.rotateButton2 = itemView.findViewById(R.id.rotate2_card);
        holder.frontView = itemView.findViewById(R.id.frontImage);
        holder.backView = itemView.findViewById(R.id.backImage);
        holder.frontCardView = itemView.findViewById(R.id.cardfrontView);
        holder.backCardView = itemView.findViewById(R.id.cardBackView);
        loadAnimations();
        changeCameraDistance(holder);
        if(holder.definitionView.getText().toString().length()>50){
            holder.definitionView.setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM);
        }

        holder.rotateButton.setOnClickListener(v -> flipCard(holder));
        holder.rotateButton2.setOnClickListener(v -> flipCard(holder));
        holder.addButton.setOnClickListener(v -> {
            PopupMenu popupMenu = new PopupMenu( FlashcardRecyclerViewAdapter.context, holder.addButton);
            popupMenu.inflate(R.menu.menu_card);
            popupMenu.setOnMenuItemClickListener(item -> {
                switch (item.getItemId()){
                    case R.id.add_text:
                        editTextDialog(parent,true);
                        break;
                    case R.id.paint:
                        startPaintIntent(_ID,true);
                        break;
                    case R.id.take_photo:
                        startCamera(_ID,true);
                        break;
                    case R.id.upload:
                        FlashcardRecyclerViewAdapter.isFront = true;
                        new Chooser().startChooser(FlashcardRecyclerViewAdapter.context);
                        break;

                    default:
                        throw new IllegalStateException("Unexpected value: " + item.getItemId());
                }
                return false;
            });

            popupMenu.show();
        });
        holder.addButton2.setOnClickListener(v -> {
            PopupMenu popupMenu = new PopupMenu( FlashcardRecyclerViewAdapter.context, holder.addButton2);
            popupMenu.inflate(R.menu.menu_card);
            popupMenu.setOnMenuItemClickListener(item -> {
                switch (item.getItemId()){
                    case R.id.add_text:
                        editTextDialog(parent,false);
                        break;
                    case R.id.paint:
                        startPaintIntent(_ID,false
                        );
                        break;
                    case R.id.take_photo:
                        startCamera(_ID,false);
                        break;
                    case R.id.upload:
                        FlashcardRecyclerViewAdapter.isFront =false;
                        new Chooser().startChooser(FlashcardRecyclerViewAdapter.context);
                        break;

                    default:
                        throw new IllegalStateException("Unexpected value: " + item.getItemId());
                }
                return false;
            });

            popupMenu.show();
        });

        holder.closeButton.setOnClickListener(v -> deleteCard(_ID));
        return holder;
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, Cursor cursor1) {
        cardViewHolder viewHolder = (cardViewHolder) holder;
        cursor1.moveToPosition(cursor1.getPosition());
        viewHolder.setData(cursor1);
    }

    @Override
    public int getItemCount() {
        return super.getItemCount();
    }


    public boolean IsWellFormedUri(String uriString ){
        File file = new File(uriString);
        Uri uri = Uri.parse(uriString);
        return uri.isAbsolute() || file.isFile();
    }

    public void deleteCard(long id){
        FlashContract.CardEntry.TABLE_NAME = TABLE_ID;
        Uri uri = ContentUris.withAppendedId(FlashContract.CardEntry.CONTENT_URI,id);

        int rowDeleted = context.getContentResolver().delete(uri,null,null);
        if(rowDeleted != 0){
            Log.d("Adapter",rowDeleted+" Successfully");
        }else {
            Log.d("Adapter",rowDeleted+" Unsuccessful");
        }
        notifyDataSetChanged();
    }

    public void changeCameraDistance(cardViewHolder holder){
        int distance = 8000;
        float scale = context.getResources().getDisplayMetrics().density * distance;
        holder.frontCardView.setCameraDistance(scale);
        holder.backCardView.setCameraDistance(scale);
    }

    private void loadAnimations(){
        rightOut = (AnimatorSet) AnimatorInflater.loadAnimator(context,R.animator.out_animation);
        leftIn = (AnimatorSet) AnimatorInflater.loadAnimator(context,R.animator.in_animation);
        rightOut.setDuration(1000);
        leftIn.setDuration(1000);
    }

    public void flipCard(cardViewHolder holder){
        if(!isBackVisible){
            rightOut.setTarget(holder.frontCardView);
            leftIn.setTarget(holder.backCardView);
            rightOut.start();
            leftIn.start();
            leftIn.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    holder.frontCardView.setVisibility(View.GONE);
                    holder.backCardView.setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            isBackVisible = true;
        }else {
            rightOut.setTarget(holder.backCardView);
            leftIn.setTarget(holder.frontCardView);
            leftIn.start();
            rightOut.start();

            rightOut.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    holder.backCardView.setVisibility(View.GONE);
                    holder.frontCardView.setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });

            isBackVisible = false;
        }
    }

    public void writeToDatabase(long id, String key, String value){
        FlashContract.CardEntry.TABLE_NAME = TABLE_ID;
        ContentValues values = new ContentValues();
        Uri uri = ContentUris.withAppendedId(FlashContract.CardEntry.CONTENT_URI,id);
        values.put(key,value);
        context.getContentResolver().update(uri,values,null,null);
        notifyDataSetChanged();
    }

    public void startCamera(long id, boolean isFront){
        Intent cameraIntent = new Intent(context, CameraXActivity.class);
        Uri uri = ContentUris.withAppendedId(FlashContract.CardEntry.CONTENT_URI,id);
        cameraIntent.setData(uri);
        cameraIntent.putExtra("isFront",isFront);
        context.startActivity(cameraIntent);
        notifyDataSetChanged();
    }

    public void startPaintIntent(long id, boolean isFront){
        Intent paintIntent = new Intent(context, PaintActivity.class);
        Uri uri = ContentUris.withAppendedId(FlashContract.CardEntry.CONTENT_URI,id);
        paintIntent.setData(uri);
        paintIntent.putExtra("isFront",isFront);
        context.startActivity(paintIntent);
        notifyDataSetChanged();
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public void getImageUri(Uri uri){
        if(isFront) {
            writeToDatabase(_ID, FlashContract.CardEntry.COLUMN_TERM, String.valueOf(uri));
        }else {
            writeToDatabase(_ID, FlashContract.CardEntry.COLUMN_DEFINITION, String.valueOf(uri));
        }

        File sourceFile = new File(String.valueOf(uri));

        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/Android/data/"+context.getPackageName()+".uploads");
        myDir.mkdirs();
        String filename = sourceFile.getName()+ Calendar.getInstance().getTimeInMillis();
        String destinationPath = myDir+filename;
        File destinationFile = new File(destinationPath);
        try{
            copyFile(sourceFile,destinationFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    @RequiresApi(api = Build.VERSION_CODES.Q)
    public void copyFile(File source, File destination) throws
            IOException{
        FileUtils.copy(new FileInputStream(source), new FileOutputStream(destination));
    }


    public static void reduceTextSize(@NotNull TextView textView, @NotNull View parentView){
        while (textView.getHeight() > parentView.getHeight()){
            float textSize = textView.getTextSize();
            float newSize = (float) (0.5*parentView.getHeight());
            textSize = textSize - newSize;
            textView.setTextSize(textSize);
        }
    }

    public void editTextDialog(ViewGroup viewGroup, boolean isFront){
        View dialog_view = LayoutInflater.from(context).inflate(R.layout.add_text_dialog,viewGroup,false);

        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setView(dialog_view);

        TextInputEditText addText = dialog_view.findViewById(R.id.addText);
        if(isFront == true){
        addText.setHint("Enter a question or a term or a word");
        }else {
            addText.setHint("Enter the Definition / Theorem / Answer to the Question or the Explanation of the word ");
        }
        builder.setPositiveButton("done", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String text = addText.getText().toString().trim();
                if(isFront == true){
                    writeToDatabase(_ID, FlashContract.CardEntry.COLUMN_TERM,text);
                    notifyDataSetChanged();
                }else {
                    writeToDatabase(_ID, FlashContract.CardEntry.COLUMN_DEFINITION,text);
                    notifyDataSetChanged();
                }
            }
        });

        builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if(dialog != null){
                    dialog.dismiss();
                }
            }
        });
        final AlertDialog alertDialog  = builder.create();
        alertDialog.show();
    }


}
public class cardViewHolder extends RecyclerView.ViewHolder {
    public TextView termView, definitionView;
    public ImageButton addButton, closeButton, rotateButton, rotateButton2, addButton2;
    public ImageView frontView, backView;
    public View frontCardView, backCardView;
    public String term;
    public String definition;

    @RequiresApi(api = Build.VERSION_CODES.O)
    public cardViewHolder(@NonNull View itemView) {
        super(itemView);

    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    public void setData(Cursor cursor){
        int idColumnIndex = cursor.getColumnIndexOrThrow(FlashContract.CardEntry._ID);
        int setIDColumnIndex = cursor.getColumnIndexOrThrow(FlashContract.CardEntry.CARD_SET_ID);
        int termColumnIndex = cursor.getColumnIndexOrThrow(FlashContract.CardEntry.COLUMN_TERM);
        int definitionColumnIndex = cursor.getColumnIndexOrThrow(FlashContract.CardEntry.COLUMN_DEFINITION);
        _ID = cursor.getLong(idColumnIndex);
        String setId = cursor.getString(setIDColumnIndex);
        String term = cursor.getString(termColumnIndex);
        String definition = cursor.getString(definitionColumnIndex);
       


        TABLE_ID = setId;

        if(IsWellFormedUri(term)){
            frontView.setVisibility(View.VISIBLE);
            termView.setVisibility(View.GONE);
            Picasso.get().load(term).fit().into(frontView);
        }else {
            if(term.length() <= 50){
                termView.setTextSize(22);
            }else {
                termView.setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_NONE);
            }
            frontView.setVisibility(View.GONE);
            termView.setVisibility(View.VISIBLE);
            termView.setText(term);
        }

        if(IsWellFormedUri(definition)){
            if(definition.length() <= 50){
                definitionView.setTextSize(22);
            }else {
                definitionView.setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM);
            }
            backView.setVisibility(View.VISIBLE);
            definitionView.setVisibility(View.GONE);
            Picasso.get().load(definition).fit().into(backView);
        }else {
            backView.setVisibility(View.GONE);
            definitionView.setVisibility(View.VISIBLE);
            definitionView.setText(definition);
        }
    }

    public boolean IsWellFormedUri(String uriString ){
        File file = new File(uriString);
        Uri uri = Uri.parse(uriString);
        return uri.isAbsolute() || file.isFile();
    }
}
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:id="@+id/card_layout"
        android:layout_height="500dp">
    
        <include
            android:id="@+id/cardBackView"
            layout="@layout/flashcard_back_view"
             />
        <include
            android:id="@+id/cardfrontView"
            layout="@layout/flashcard_front_view"/>
    </RelativeLayout>