Крупное обновление 2.0
This commit is contained in:
		
							parent
							
								
									f6d29f1fb9
								
							
						
					
					
						commit
						a67d6d4e7b
					
				
							
								
								
									
										8
									
								
								.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
								
							@ -4,6 +4,14 @@
 | 
			
		||||
    <selectionStates>
 | 
			
		||||
      <SelectionState runConfigName="app">
 | 
			
		||||
        <option name="selectionMode" value="DROPDOWN" />
 | 
			
		||||
        <DropdownSelection timestamp="2025-05-17T08:55:13.914480200Z">
 | 
			
		||||
          <Target type="DEFAULT_BOOT">
 | 
			
		||||
            <handle>
 | 
			
		||||
              <DeviceId pluginId="PhysicalDevice" identifier="serial=28161JEGR06778" />
 | 
			
		||||
            </handle>
 | 
			
		||||
          </Target>
 | 
			
		||||
        </DropdownSelection>
 | 
			
		||||
        <DialogSelection />
 | 
			
		||||
      </SelectionState>
 | 
			
		||||
    </selectionStates>
 | 
			
		||||
  </component>
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,8 @@ android {
 | 
			
		||||
        versionName = "1.0"
 | 
			
		||||
 | 
			
		||||
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildTypes {
 | 
			
		||||
@ -35,7 +37,6 @@ android {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
 | 
			
		||||
    implementation(libs.appcompat)
 | 
			
		||||
    implementation(libs.material)
 | 
			
		||||
    implementation(libs.constraintlayout)
 | 
			
		||||
@ -43,6 +44,11 @@ dependencies {
 | 
			
		||||
    implementation(libs.lifecycle.viewmodel.ktx)
 | 
			
		||||
    implementation(libs.navigation.fragment)
 | 
			
		||||
    implementation(libs.navigation.ui)
 | 
			
		||||
 | 
			
		||||
    implementation("androidx.room:room-runtime:2.7.1")
 | 
			
		||||
    implementation(libs.room.common.jvm)
 | 
			
		||||
    annotationProcessor("androidx.room:room-compiler:2.7.1")
 | 
			
		||||
 | 
			
		||||
    testImplementation(libs.junit)
 | 
			
		||||
    androidTestImplementation(libs.ext.junit)
 | 
			
		||||
    androidTestImplementation(libs.espresso.core)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								app/src/main/java/com/kolobochki/memory/AppDatabase.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/src/main/java/com/kolobochki/memory/AppDatabase.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Database;
 | 
			
		||||
import androidx.room.Room;
 | 
			
		||||
import androidx.room.RoomDatabase;
 | 
			
		||||
 | 
			
		||||
@Database(
 | 
			
		||||
        entities = {LevelRecord.class},
 | 
			
		||||
        version = 1,
 | 
			
		||||
        exportSchema = true
 | 
			
		||||
)
 | 
			
		||||
public abstract class AppDatabase extends RoomDatabase {
 | 
			
		||||
    public abstract LevelRecordDao levelRecordDao();
 | 
			
		||||
 | 
			
		||||
    private static volatile AppDatabase INSTANCE;
 | 
			
		||||
 | 
			
		||||
    public static AppDatabase getDatabase(Context context) {
 | 
			
		||||
        if (INSTANCE == null) {
 | 
			
		||||
            synchronized (AppDatabase.class) {
 | 
			
		||||
                if (INSTANCE == null) {
 | 
			
		||||
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
 | 
			
		||||
                                    AppDatabase.class, "memory-db")
 | 
			
		||||
                            .fallbackToDestructiveMigration()
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								app/src/main/java/com/kolobochki/memory/GameRepository.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								app/src/main/java/com/kolobochki/memory/GameRepository.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import androidx.lifecycle.LiveData;
 | 
			
		||||
import androidx.lifecycle.MutableLiveData;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class GameRepository {
 | 
			
		||||
    private final LevelRecordDao recordDao;
 | 
			
		||||
 | 
			
		||||
    public GameRepository(LevelRecordDao recordDao) {
 | 
			
		||||
        this.recordDao = recordDao;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Сохранить результат уровня
 | 
			
		||||
    public void saveLevelResult(int levelId, int score) {
 | 
			
		||||
        new Thread(() -> {
 | 
			
		||||
            LevelRecord existing = recordDao.getRecordForLevel(levelId);
 | 
			
		||||
 | 
			
		||||
            if (existing == null) {
 | 
			
		||||
                // Первая попытка на этом уровне
 | 
			
		||||
                recordDao.insert(new LevelRecord(levelId, score, 1));
 | 
			
		||||
            } else {
 | 
			
		||||
                // Обновляем если результат лучше
 | 
			
		||||
                recordDao.updateIfBetter(levelId, score);
 | 
			
		||||
                if (score <= existing.bestScore) {
 | 
			
		||||
                    // Просто увеличиваем счётчик попыток
 | 
			
		||||
                    existing.attemptsCount++;
 | 
			
		||||
                    recordDao.update(existing);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }).start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Получить все записи
 | 
			
		||||
    public LiveData<List<LevelRecord>> getAllRecords() {
 | 
			
		||||
        MutableLiveData<List<LevelRecord>> liveData = new MutableLiveData<>();
 | 
			
		||||
        new Thread(() -> {
 | 
			
		||||
            liveData.postValue(recordDao.getAllRecords());
 | 
			
		||||
        }).start();
 | 
			
		||||
        return liveData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Сбросить все данные
 | 
			
		||||
    public void resetAllData() {
 | 
			
		||||
        new Thread(() -> {
 | 
			
		||||
            recordDao.deleteAllRecords();
 | 
			
		||||
        }).start();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								app/src/main/java/com/kolobochki/memory/LevelRecord.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/src/main/java/com/kolobochki/memory/LevelRecord.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Entity;
 | 
			
		||||
import androidx.room.PrimaryKey;
 | 
			
		||||
 | 
			
		||||
@Entity(tableName = "level_records")
 | 
			
		||||
public class LevelRecord {
 | 
			
		||||
    @PrimaryKey
 | 
			
		||||
    public int levelId;
 | 
			
		||||
 | 
			
		||||
    public int bestScore;
 | 
			
		||||
    public int attemptsCount;
 | 
			
		||||
    public long lastPlayedTime;
 | 
			
		||||
 | 
			
		||||
    public LevelRecord(int levelId, int bestScore, int attemptsCount) {
 | 
			
		||||
        this.levelId = levelId;
 | 
			
		||||
        this.bestScore = bestScore;
 | 
			
		||||
        this.attemptsCount = attemptsCount;
 | 
			
		||||
        this.lastPlayedTime = System.currentTimeMillis();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								app/src/main/java/com/kolobochki/memory/LevelRecordDao.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/src/main/java/com/kolobochki/memory/LevelRecordDao.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Dao;
 | 
			
		||||
import androidx.room.Insert;
 | 
			
		||||
import androidx.room.Query;
 | 
			
		||||
import androidx.room.Update;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Dao
 | 
			
		||||
public interface LevelRecordDao {
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insert(LevelRecord record);
 | 
			
		||||
 | 
			
		||||
    @Update
 | 
			
		||||
    void update(LevelRecord record);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM level_records WHERE levelId = :levelId")
 | 
			
		||||
    LevelRecord getRecordForLevel(int levelId);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM level_records ORDER BY levelId ASC")
 | 
			
		||||
    List<LevelRecord> getAllRecords();
 | 
			
		||||
 | 
			
		||||
    @Query("DELETE FROM level_records")
 | 
			
		||||
    void deleteAllRecords();
 | 
			
		||||
 | 
			
		||||
    @Query("UPDATE level_records SET bestScore = :newScore, attemptsCount = attemptsCount + 1 WHERE levelId = :levelId AND :newScore > bestScore")
 | 
			
		||||
    void updateIfBetter(int levelId, int newScore);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -10,18 +10,33 @@ import androidx.navigation.NavController;
 | 
			
		||||
import androidx.navigation.Navigation;
 | 
			
		||||
import androidx.navigation.ui.AppBarConfiguration;
 | 
			
		||||
import androidx.navigation.ui.NavigationUI;
 | 
			
		||||
import androidx.room.Room;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.databinding.ActivityMainBinding;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.AppDatabase;
 | 
			
		||||
import com.kolobochki.memory.GameRepository;
 | 
			
		||||
 | 
			
		||||
public class MainActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private ActivityMainBinding binding;
 | 
			
		||||
    private NavController navController;
 | 
			
		||||
 | 
			
		||||
    private GameRepository gameRepository;
 | 
			
		||||
    private static AppDatabase database;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
        database = Room.databaseBuilder(getApplicationContext(),
 | 
			
		||||
                        AppDatabase.class, "memory-db")
 | 
			
		||||
                .fallbackToDestructiveMigration()
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        gameRepository = new GameRepository(database.levelRecordDao());
 | 
			
		||||
 | 
			
		||||
        binding = ActivityMainBinding.inflate(getLayoutInflater());
 | 
			
		||||
        setContentView(binding.getRoot());
 | 
			
		||||
 | 
			
		||||
@ -33,7 +48,9 @@ public class MainActivity extends AppCompatActivity {
 | 
			
		||||
                R.id.navigation_task1,
 | 
			
		||||
                R.id.navigation_task2,
 | 
			
		||||
                R.id.navigation_task3,
 | 
			
		||||
                R.id.navigation_task4)
 | 
			
		||||
                R.id.navigation_task4,
 | 
			
		||||
                R.id.navigation_info,
 | 
			
		||||
                R.id.navigation_records)
 | 
			
		||||
                .build();
 | 
			
		||||
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
 | 
			
		||||
        NavigationUI.setupWithNavController(binding.navView, navController);
 | 
			
		||||
@ -42,12 +59,31 @@ public class MainActivity extends AppCompatActivity {
 | 
			
		||||
            if (destination.getId() == R.id.navigation_task1
 | 
			
		||||
             || destination.getId() == R.id.navigation_task2
 | 
			
		||||
             || destination.getId() == R.id.navigation_task3
 | 
			
		||||
             || destination.getId() == R.id.navigation_task4) {
 | 
			
		||||
             || destination.getId() == R.id.navigation_task4
 | 
			
		||||
             || destination.getId() == R.id.navigation_info
 | 
			
		||||
             || destination.getId() == R.id.navigation_records) {
 | 
			
		||||
                binding.navView.setVisibility(View.GONE);
 | 
			
		||||
            } else {
 | 
			
		||||
                binding.navView.setVisibility(View.VISIBLE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public GameRepository getGameRepository() {
 | 
			
		||||
        return gameRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static AppDatabase getDatabase() {
 | 
			
		||||
        return database;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onDestroy() {
 | 
			
		||||
        if (database != null && database.isOpen()) {
 | 
			
		||||
            database.close();
 | 
			
		||||
        }
 | 
			
		||||
        super.onDestroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										132
									
								
								app/src/main/java/com/kolobochki/memory/fragment_info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								app/src/main/java/com/kolobochki/memory/fragment_info.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.activity.OnBackPressedCallback;
 | 
			
		||||
import androidx.appcompat.app.ActionBar;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.navigation.NavController;
 | 
			
		||||
import androidx.navigation.Navigation;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import com.kolobochki.memory.R;
 | 
			
		||||
import com.kolobochki.memory.databinding.FragmentDashboardBinding;
 | 
			
		||||
import com.kolobochki.memory.databinding.FragmentInfoBinding;
 | 
			
		||||
 | 
			
		||||
public class fragment_info extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private FragmentInfoBinding binding;
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
 | 
			
		||||
    private TextView helpText;
 | 
			
		||||
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
    private String mParam2;
 | 
			
		||||
    private OnBackPressedCallback backPressedCallback;
 | 
			
		||||
    private String previousTitle;
 | 
			
		||||
 | 
			
		||||
    public fragment_info() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static fragment_info newInstance(String param1, String param2) {
 | 
			
		||||
        fragment_info fragment = new fragment_info();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(ARG_PARAM1, param1);
 | 
			
		||||
        args.putString(ARG_PARAM2, param2);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            mParam1 = getArguments().getString(ARG_PARAM1);
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (getActivity() instanceof AppCompatActivity) {
 | 
			
		||||
            ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
 | 
			
		||||
            if (actionBar != null) {
 | 
			
		||||
                actionBar.setTitle("Инструкция");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        binding = com.kolobochki.memory.databinding.FragmentInfoBinding .inflate(inflater, container, false);
 | 
			
		||||
        View root = binding.getRoot();
 | 
			
		||||
 | 
			
		||||
        String instructions =
 | 
			
		||||
                "1. Найти пары:\n" +
 | 
			
		||||
                        "   - На экране карточки перевернуты рубашкой вверх\n" +
 | 
			
		||||
                        "   - Открывайте по две карточки, чтобы найти пары\n" +
 | 
			
		||||
                        "   - Совпавшие карточки остаются открытыми\n" +
 | 
			
		||||
                        "   - Цель: открыть все пары за минимальное время\n\n" +
 | 
			
		||||
 | 
			
		||||
                        "2. Саймон говорит:\n" +
 | 
			
		||||
                        "   - Саймон показывает последовательность цветов\n" +
 | 
			
		||||
                        "   - Повторите показанную последовательность\n" +
 | 
			
		||||
                        "   - С каждым уровнем последовательность удлиняется\n" +
 | 
			
		||||
                        "   - Ошибка завершает игру\n\n" +
 | 
			
		||||
 | 
			
		||||
                        "3. Числовая матрица:\n" +
 | 
			
		||||
                        "   - Запомните расположение чисел в матрице\n" +
 | 
			
		||||
                        "   - Восстановите числа после их исчезновения\n" +
 | 
			
		||||
                        "   - Сложность повышается с каждым уровнем\n\n" +
 | 
			
		||||
 | 
			
		||||
                        "4. Найти лишнее:\n" +
 | 
			
		||||
                        "   - Среди нескольких объектов найдите отличающийся\n" +
 | 
			
		||||
                        "   - Выберите лишний объект\n" +
 | 
			
		||||
                        "   - Время на ответ ограничено";
 | 
			
		||||
 | 
			
		||||
        binding.textView.setText(instructions);
 | 
			
		||||
 | 
			
		||||
        return root;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void navigateHome() {
 | 
			
		||||
        NavController navController = Navigation.findNavController(requireView());
 | 
			
		||||
        navController.popBackStack();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroyView() {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
        if (backPressedCallback != null) {
 | 
			
		||||
            backPressedCallback.remove();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        if (getActivity() != null && ((AppCompatActivity)getActivity()).getSupportActionBar() != null) {
 | 
			
		||||
            ((AppCompatActivity)getActivity()).getSupportActionBar().hide();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onPause() {
 | 
			
		||||
        super.onPause();
 | 
			
		||||
        if (getActivity() != null && ((AppCompatActivity)getActivity()).getSupportActionBar() != null) {
 | 
			
		||||
            ((AppCompatActivity)getActivity()).getSupportActionBar().show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (getActivity() instanceof AppCompatActivity) {
 | 
			
		||||
            ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
 | 
			
		||||
            if (actionBar != null && previousTitle != null) {
 | 
			
		||||
                actionBar.setTitle(previousTitle);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								app/src/main/java/com/kolobochki/memory/fragment_records.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								app/src/main/java/com/kolobochki/memory/fragment_records.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,145 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import androidx.activity.OnBackPressedCallback;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.app.ActionBar;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import com.kolobochki.memory.AppDatabase;
 | 
			
		||||
import com.kolobochki.memory.LevelRecord;
 | 
			
		||||
import com.kolobochki.memory.LevelRecordDao;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
public class fragment_records extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private RecyclerView recyclerView;
 | 
			
		||||
    private StatsAdapter adapter;
 | 
			
		||||
    private LevelRecordDao levelRecordDao;
 | 
			
		||||
    private Executor executor = Executors.newSingleThreadExecutor();
 | 
			
		||||
 | 
			
		||||
    private OnBackPressedCallback backPressedCallback;
 | 
			
		||||
    private String previousTitle;
 | 
			
		||||
 | 
			
		||||
    // Названия уровней
 | 
			
		||||
    private final String[] levelNames = {
 | 
			
		||||
            "Найти пары",
 | 
			
		||||
            "Саймон говорит",
 | 
			
		||||
            "Числовая матрица",
 | 
			
		||||
            "Найти лишнее"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(@Nullable Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
        // Инициализация базы данных
 | 
			
		||||
        AppDatabase db = AppDatabase.getDatabase(requireContext().getApplicationContext());
 | 
			
		||||
        levelRecordDao = db.levelRecordDao();
 | 
			
		||||
 | 
			
		||||
        if (getActivity() instanceof AppCompatActivity) {
 | 
			
		||||
            ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
 | 
			
		||||
            if (actionBar != null) {
 | 
			
		||||
                actionBar.setTitle("Мой прогресс");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_records, container, false);
 | 
			
		||||
 | 
			
		||||
        recyclerView = view.findViewById(R.id.stats_recycler);
 | 
			
		||||
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        adapter = new StatsAdapter();
 | 
			
		||||
        recyclerView.setAdapter(adapter);
 | 
			
		||||
 | 
			
		||||
        loadStats();
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadStats() {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            try {
 | 
			
		||||
                List<LevelRecord> records = levelRecordDao.getAllRecords();
 | 
			
		||||
 | 
			
		||||
                // Если записей нет - создаем пустые
 | 
			
		||||
                if (records == null || records.isEmpty()) {
 | 
			
		||||
                    for (int i = 1; i <= 4; i++) {
 | 
			
		||||
                        LevelRecord record = new LevelRecord(i, 0, 0);
 | 
			
		||||
                        levelRecordDao.insert(record);
 | 
			
		||||
                    }
 | 
			
		||||
                    records = levelRecordDao.getAllRecords();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                List<LevelRecord> finalRecords = records;
 | 
			
		||||
                requireActivity().runOnUiThread(() -> {
 | 
			
		||||
                    if (adapter != null) {
 | 
			
		||||
                        adapter.setRecords(finalRecords);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                requireActivity().runOnUiThread(() ->
 | 
			
		||||
                        Toast.makeText(requireContext(), "Ошибка загрузки данных", Toast.LENGTH_SHORT).show()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Адаптер для RecyclerView
 | 
			
		||||
    private class StatsAdapter extends RecyclerView.Adapter<StatsAdapter.StatsViewHolder> {
 | 
			
		||||
 | 
			
		||||
        private List<LevelRecord> records;
 | 
			
		||||
 | 
			
		||||
        public void setRecords(List<LevelRecord> records) {
 | 
			
		||||
            this.records = records;
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @NonNull
 | 
			
		||||
        @Override
 | 
			
		||||
        public StatsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
            View view = LayoutInflater.from(parent.getContext())
 | 
			
		||||
                    .inflate(R.layout.item_level_stat, parent, false);
 | 
			
		||||
            return new StatsViewHolder(view);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onBindViewHolder(@NonNull StatsViewHolder holder, int position) {
 | 
			
		||||
            LevelRecord record = records.get(position);
 | 
			
		||||
            holder.levelName.setText(levelNames[record.levelId - 1]);
 | 
			
		||||
            holder.bestScore.setText("Рекорд: " + record.bestScore);
 | 
			
		||||
            holder.attempts.setText("Попыток: " + record.attemptsCount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getItemCount() {
 | 
			
		||||
            return records != null ? records.size() : 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        class StatsViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
            TextView levelName, bestScore, attempts;
 | 
			
		||||
 | 
			
		||||
            StatsViewHolder(View itemView) {
 | 
			
		||||
                super(itemView);
 | 
			
		||||
                levelName = itemView.findViewById(R.id.level_name);
 | 
			
		||||
                bestScore = itemView.findViewById(R.id.best_score);
 | 
			
		||||
                attempts = itemView.findViewById(R.id.attempts_count);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,8 @@
 | 
			
		||||
package com.kolobochki.memory;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.appcompat.app.ActionBar;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
@ -14,17 +12,23 @@ import android.widget.ImageView;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import androidx.activity.OnBackPressedCallback;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import androidx.navigation.NavController;
 | 
			
		||||
import androidx.navigation.Navigation;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.room.Room;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.AppDatabase;
 | 
			
		||||
import com.kolobochki.memory.LevelRecord;
 | 
			
		||||
import com.kolobochki.memory.LevelRecordDao;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.R;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
public class fragment_task1 extends Fragment {
 | 
			
		||||
 | 
			
		||||
@ -35,43 +39,34 @@ public class fragment_task1 extends Fragment {
 | 
			
		||||
    private OnBackPressedCallback backPressedCallback;
 | 
			
		||||
    private String previousTitle;
 | 
			
		||||
 | 
			
		||||
    // ----------------------------------------------
 | 
			
		||||
 | 
			
		||||
    private static final int PAIRS_COUNT = 6; // Кол-во пар
 | 
			
		||||
    private static final int GRID_COLUMNS = 4; // Кол-во колонок
 | 
			
		||||
    private static final int PREVIEW_TIME = 5000; // Задержка в начале в мс
 | 
			
		||||
    private static final int SUCCESS_DELAY = 4000; // Задержка в конце в мс
 | 
			
		||||
    private static final int INITIAL_LIVES = 3; // Кол-во жизек
 | 
			
		||||
 | 
			
		||||
    // ----------------------------------------------
 | 
			
		||||
    // Game constants
 | 
			
		||||
    private static final int PAIRS_COUNT = 6;
 | 
			
		||||
    private static final int GRID_COLUMNS = 4;
 | 
			
		||||
    private static final int PREVIEW_TIME = 5000;
 | 
			
		||||
    private static final int SUCCESS_DELAY = 4000;
 | 
			
		||||
    private static final int INITIAL_LIVES = 3;
 | 
			
		||||
    private static final int LEVEL_ID = 1; // ID для первого уровня
 | 
			
		||||
 | 
			
		||||
    // Game variables
 | 
			
		||||
    private int score = 0;
 | 
			
		||||
    private int lives = INITIAL_LIVES;
 | 
			
		||||
    private int flippedCount = 0;
 | 
			
		||||
    private ImageView firstFlipped = null;
 | 
			
		||||
    private boolean isPreview = true;
 | 
			
		||||
    private boolean isGameComplete = false;
 | 
			
		||||
 | 
			
		||||
    // ----------------------------------------------
 | 
			
		||||
 | 
			
		||||
    // Views
 | 
			
		||||
    private GridLayout gridLayout;
 | 
			
		||||
    private ProgressBar progressBar;
 | 
			
		||||
    private List<Integer> tileImages = new ArrayList<>();
 | 
			
		||||
    private List<ImageView> tiles = new ArrayList<>();
 | 
			
		||||
    private LinearLayout livesLayout;
 | 
			
		||||
 | 
			
		||||
    // -----------------------------------------------
 | 
			
		||||
    // Database
 | 
			
		||||
    private AppDatabase database;
 | 
			
		||||
    private LevelRecordDao levelRecordDao;
 | 
			
		||||
    private Executor executor = Executors.newSingleThreadExecutor();
 | 
			
		||||
 | 
			
		||||
    public fragment_task1() { }
 | 
			
		||||
 | 
			
		||||
    public static fragment_task1 newInstance(String param1, String param2) {
 | 
			
		||||
        fragment_task1 fragment = new fragment_task1();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(ARG_PARAM1, param1);
 | 
			
		||||
        args.putString(ARG_PARAM2, param2);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
    public fragment_task1() {}
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
@ -81,7 +76,10 @@ public class fragment_task1 extends Fragment {
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) {
 | 
			
		||||
        database = AppDatabase.getDatabase(requireContext());
 | 
			
		||||
        levelRecordDao = database.levelRecordDao();
 | 
			
		||||
 | 
			
		||||
        backPressedCallback = new OnBackPressedCallback(true) {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void handleOnBackPressed() {
 | 
			
		||||
                if (!isGameComplete) {
 | 
			
		||||
@ -168,7 +166,6 @@ public class fragment_task1 extends Fragment {
 | 
			
		||||
        }, PREVIEW_TIME);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private void flipAllTiles() {
 | 
			
		||||
        for (ImageView tile : tiles) {
 | 
			
		||||
            tile.setImageResource(R.drawable.tile_back);
 | 
			
		||||
@ -233,11 +230,13 @@ public class fragment_task1 extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private void gameComplete() {
 | 
			
		||||
        isGameComplete = true;
 | 
			
		||||
        saveGameResult(true);
 | 
			
		||||
        new Handler().postDelayed(this::navigateHome, 1500);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void gameOver() {
 | 
			
		||||
        isGameComplete = true;
 | 
			
		||||
        saveGameResult(false);
 | 
			
		||||
        new AlertDialog.Builder(requireContext())
 | 
			
		||||
                .setTitle("Игра окончена")
 | 
			
		||||
                .setMessage("Вы проиграли. Попробуйте еще раз!")
 | 
			
		||||
@ -246,6 +245,49 @@ public class fragment_task1 extends Fragment {
 | 
			
		||||
                .show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void saveGameResult(boolean isWin) {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            try {
 | 
			
		||||
                LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
 | 
			
		||||
                if (existingRecord == null) {
 | 
			
		||||
                    // Первая запись для этого уровня
 | 
			
		||||
                    LevelRecord newRecord = new LevelRecord(LEVEL_ID, isWin ? score : 0, 1);
 | 
			
		||||
                    levelRecordDao.insert(newRecord);
 | 
			
		||||
 | 
			
		||||
                    if (isWin) {
 | 
			
		||||
                        showNewRecordToast(score);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    boolean isNewRecord = false;
 | 
			
		||||
 | 
			
		||||
                    if (isWin && score > existingRecord.bestScore) {
 | 
			
		||||
                        existingRecord.bestScore = score;
 | 
			
		||||
                        isNewRecord = true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    existingRecord.attemptsCount++;
 | 
			
		||||
                    levelRecordDao.update(existingRecord);
 | 
			
		||||
 | 
			
		||||
                    if (isNewRecord) {
 | 
			
		||||
                        showNewRecordToast(score);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                requireActivity().runOnUiThread(() ->
 | 
			
		||||
                        Toast.makeText(requireContext(), "Ошибка сохранения: " + e.getMessage(), Toast.LENGTH_SHORT).show()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showNewRecordToast(int score) {
 | 
			
		||||
        requireActivity().runOnUiThread(() -> {
 | 
			
		||||
            Toast.makeText(requireContext(),
 | 
			
		||||
                    "Новый рекорд: " + score, Toast.LENGTH_SHORT).show();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void navigateHome() {
 | 
			
		||||
        NavController navController = Navigation.findNavController(requireView());
 | 
			
		||||
        navController.popBackStack();
 | 
			
		||||
@ -257,6 +299,9 @@ public class fragment_task1 extends Fragment {
 | 
			
		||||
        if (backPressedCallback != null) {
 | 
			
		||||
            backPressedCallback.remove();
 | 
			
		||||
        }
 | 
			
		||||
        if (database != null) {
 | 
			
		||||
            database.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showExitConfirmationDialog() {
 | 
			
		||||
 | 
			
		||||
@ -3,35 +3,38 @@ package com.kolobochki.memory;
 | 
			
		||||
import static com.kolobochki.memory.R.*;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.activity.OnBackPressedCallback;
 | 
			
		||||
import androidx.appcompat.app.ActionBar;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import androidx.navigation.NavController;
 | 
			
		||||
import androidx.navigation.Navigation;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.GridLayout;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.R;
 | 
			
		||||
import com.kolobochki.memory.AppDatabase;
 | 
			
		||||
import com.kolobochki.memory.LevelRecord;
 | 
			
		||||
import com.kolobochki.memory.LevelRecordDao;
 | 
			
		||||
 | 
			
		||||
public class fragment_task2 extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
    private static final int LEVEL_ID = 2; // ID для второго уровня
 | 
			
		||||
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
    private String mParam2;
 | 
			
		||||
@ -50,6 +53,11 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
    private TextView roundText, livesText;
 | 
			
		||||
    private GridLayout buttonsGrid;
 | 
			
		||||
 | 
			
		||||
    // Database
 | 
			
		||||
    private AppDatabase database;
 | 
			
		||||
    private LevelRecordDao levelRecordDao;
 | 
			
		||||
    private Executor executor = Executors.newSingleThreadExecutor();
 | 
			
		||||
 | 
			
		||||
    private final int[] colorImages = {
 | 
			
		||||
            R.drawable.simon_red,
 | 
			
		||||
            R.drawable.simon_green,
 | 
			
		||||
@ -62,15 +70,6 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static fragment_task2 newInstance(String param1, String param2) {
 | 
			
		||||
        fragment_task2 fragment = new fragment_task2();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(ARG_PARAM1, param1);
 | 
			
		||||
        args.putString(ARG_PARAM2, param2);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
@ -79,6 +78,9 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        database = AppDatabase.getDatabase(requireContext());
 | 
			
		||||
        levelRecordDao = database.levelRecordDao();
 | 
			
		||||
 | 
			
		||||
        OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void handleOnBackPressed() {
 | 
			
		||||
@ -92,6 +94,14 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
        };
 | 
			
		||||
        requireActivity().getOnBackPressedDispatcher().addCallback(this, backPressedCallback);
 | 
			
		||||
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
            if (existingRecord != null) {
 | 
			
		||||
                existingRecord.attemptsCount++;
 | 
			
		||||
                levelRecordDao.update(existingRecord);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (getActivity() instanceof AppCompatActivity) {
 | 
			
		||||
            ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
 | 
			
		||||
            if (actionBar != null) {
 | 
			
		||||
@ -128,6 +138,7 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
        round = 1;
 | 
			
		||||
        lives = 3;
 | 
			
		||||
        currentStep = 0;
 | 
			
		||||
        isGameComplete = false;
 | 
			
		||||
        updateUI();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < 3; i++) {
 | 
			
		||||
@ -207,8 +218,10 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
                round++;
 | 
			
		||||
                currentStep = 0;
 | 
			
		||||
                updateUI();
 | 
			
		||||
                generateNextSequence();
 | 
			
		||||
 | 
			
		||||
                checkAndUpdateRecord(round);
 | 
			
		||||
 | 
			
		||||
                generateNextSequence();
 | 
			
		||||
                new Handler().postDelayed(() -> {
 | 
			
		||||
                    if (!isGameComplete) {
 | 
			
		||||
                        showSequence();
 | 
			
		||||
@ -231,6 +244,17 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkAndUpdateRecord(int currentRound) {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            LevelRecord record = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
            if (record != null && currentRound > record.bestScore) {
 | 
			
		||||
                record.bestScore = currentRound;
 | 
			
		||||
                levelRecordDao.update(record);
 | 
			
		||||
                showNewRecordToast(currentRound);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateUI() {
 | 
			
		||||
        roundText.setText("Раунд: " + round);
 | 
			
		||||
 | 
			
		||||
@ -257,6 +281,45 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
                .show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void saveGameResult(int roundsCompleted) {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            try {
 | 
			
		||||
                LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
 | 
			
		||||
                if (existingRecord == null) {
 | 
			
		||||
                    LevelRecord newRecord = new LevelRecord(LEVEL_ID, roundsCompleted, 1);
 | 
			
		||||
                    levelRecordDao.insert(newRecord);
 | 
			
		||||
                    showNewRecordToast(roundsCompleted);
 | 
			
		||||
                } else {
 | 
			
		||||
                    boolean isNewRecord = false;
 | 
			
		||||
 | 
			
		||||
                    if (roundsCompleted > existingRecord.bestScore) {
 | 
			
		||||
                        existingRecord.bestScore = roundsCompleted;
 | 
			
		||||
                        isNewRecord = true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    existingRecord.attemptsCount++;
 | 
			
		||||
                    levelRecordDao.update(existingRecord);
 | 
			
		||||
 | 
			
		||||
                    if (isNewRecord) {
 | 
			
		||||
                        showNewRecordToast(roundsCompleted);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                requireActivity().runOnUiThread(() ->
 | 
			
		||||
                        Toast.makeText(requireContext(), "Ошибка сохранения: " + e.getMessage(), Toast.LENGTH_SHORT).show()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showNewRecordToast(int score) {
 | 
			
		||||
        requireActivity().runOnUiThread(() -> {
 | 
			
		||||
            Toast.makeText(requireContext(),
 | 
			
		||||
                    "Новый рекорд: " + score + " раундов", Toast.LENGTH_SHORT).show();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showExitConfirmationDialog() {
 | 
			
		||||
        new AlertDialog.Builder(requireContext())
 | 
			
		||||
                .setTitle("Закончить упражнение?")
 | 
			
		||||
@ -296,4 +359,12 @@ public class fragment_task2 extends Fragment {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroyView() {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
        if (database != null) {
 | 
			
		||||
            database.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -23,11 +23,18 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
public class fragment_task3 extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
    private static final int LEVEL_ID = 3;
 | 
			
		||||
 | 
			
		||||
    private AppDatabase database;
 | 
			
		||||
    private LevelRecordDao levelRecordDao;
 | 
			
		||||
    private Executor executor = Executors.newSingleThreadExecutor();
 | 
			
		||||
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
    private String mParam2;
 | 
			
		||||
@ -66,6 +73,20 @@ public class fragment_task3 extends Fragment {
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        database = AppDatabase.getDatabase(requireContext());
 | 
			
		||||
        levelRecordDao = database.levelRecordDao();
 | 
			
		||||
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
            if (existingRecord != null) {
 | 
			
		||||
                existingRecord.attemptsCount++;
 | 
			
		||||
                levelRecordDao.update(existingRecord);
 | 
			
		||||
            } else {
 | 
			
		||||
                LevelRecord newRecord = new LevelRecord(LEVEL_ID, 0, 1);
 | 
			
		||||
                levelRecordDao.insert(newRecord);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void handleOnBackPressed() {
 | 
			
		||||
@ -172,6 +193,9 @@ public class fragment_task3 extends Fragment {
 | 
			
		||||
 | 
			
		||||
        if (isCorrect) {
 | 
			
		||||
            currentRound++;
 | 
			
		||||
            // Проверяем и обновляем рекорд сразу при увеличении раунда
 | 
			
		||||
            checkAndUpdateRecord(currentRound);
 | 
			
		||||
 | 
			
		||||
            Toast.makeText(getContext(), "Правильно! Раунд " + currentRound, Toast.LENGTH_SHORT).show();
 | 
			
		||||
            new Handler().postDelayed(this::setupGame, 1500);
 | 
			
		||||
        } else {
 | 
			
		||||
@ -185,6 +209,24 @@ public class fragment_task3 extends Fragment {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkAndUpdateRecord(int currentRound) {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            LevelRecord record = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
            if (record != null && currentRound > record.bestScore) {
 | 
			
		||||
                record.bestScore = currentRound;
 | 
			
		||||
                levelRecordDao.update(record);
 | 
			
		||||
                showNewRecordToast(currentRound);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showNewRecordToast(int round) {
 | 
			
		||||
        requireActivity().runOnUiThread(() -> {
 | 
			
		||||
            Toast.makeText(requireContext(),
 | 
			
		||||
                    "Новый рекорд: " + round + " раундов", Toast.LENGTH_SHORT).show();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void gameOver() {
 | 
			
		||||
        isGameComplete = true;
 | 
			
		||||
        new AlertDialog.Builder(requireContext())
 | 
			
		||||
@ -244,4 +286,12 @@ public class fragment_task3 extends Fragment {
 | 
			
		||||
        NavController navController = Navigation.findNavController(requireView());
 | 
			
		||||
        navController.popBackStack();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroyView() {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
        if (database != null) {
 | 
			
		||||
            database.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -8,6 +8,8 @@ import android.view.ViewGroup;
 | 
			
		||||
import android.widget.GridLayout;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import androidx.activity.OnBackPressedCallback;
 | 
			
		||||
import androidx.appcompat.app.ActionBar;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
@ -19,11 +21,18 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
public class fragment_task4 extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
    private static final int LEVEL_ID = 4;
 | 
			
		||||
 | 
			
		||||
    private AppDatabase database;
 | 
			
		||||
    private LevelRecordDao levelRecordDao;
 | 
			
		||||
    private Executor executor = Executors.newSingleThreadExecutor();
 | 
			
		||||
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
    private String mParam2;
 | 
			
		||||
@ -62,6 +71,20 @@ public class fragment_task4 extends Fragment {
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        database = AppDatabase.getDatabase(requireContext());
 | 
			
		||||
        levelRecordDao = database.levelRecordDao();
 | 
			
		||||
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
            if (existingRecord != null) {
 | 
			
		||||
                existingRecord.attemptsCount++;
 | 
			
		||||
                levelRecordDao.update(existingRecord);
 | 
			
		||||
            } else {
 | 
			
		||||
                LevelRecord newRecord = new LevelRecord(LEVEL_ID, 0, 1);
 | 
			
		||||
                levelRecordDao.insert(newRecord);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void handleOnBackPressed() {
 | 
			
		||||
@ -181,8 +204,9 @@ public class fragment_task4 extends Fragment {
 | 
			
		||||
        setCardsClickable(false);
 | 
			
		||||
 | 
			
		||||
        if (row == changedRow && col == changedCol) {
 | 
			
		||||
            // Correct guess
 | 
			
		||||
            round++;
 | 
			
		||||
            checkAndUpdateRecord(round);
 | 
			
		||||
 | 
			
		||||
            handler.postDelayed(() -> {
 | 
			
		||||
                if (isAdded()) startNewRound();
 | 
			
		||||
            }, 1000);
 | 
			
		||||
@ -206,6 +230,33 @@ public class fragment_task4 extends Fragment {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkAndUpdateRecord(int currentRound) {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            LevelRecord record = levelRecordDao.getRecordForLevel(LEVEL_ID);
 | 
			
		||||
            if (record != null && currentRound > record.bestScore) {
 | 
			
		||||
                record.bestScore = currentRound;
 | 
			
		||||
                levelRecordDao.update(record);
 | 
			
		||||
                showNewRecordToast(currentRound);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showNewRecordToast(int round) {
 | 
			
		||||
        requireActivity().runOnUiThread(() -> {
 | 
			
		||||
            Toast.makeText(requireContext(),
 | 
			
		||||
                    "Новый рекорд: " + round + " раундов", Toast.LENGTH_SHORT).show();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroyView() {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
        handler.removeCallbacksAndMessages(null);
 | 
			
		||||
        if (database != null) {
 | 
			
		||||
            database.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setCardImage(int row, int col, String imageName) {
 | 
			
		||||
        cards[row][col].setImageResource(getResourceId(imageName));
 | 
			
		||||
    }
 | 
			
		||||
@ -281,10 +332,4 @@ public class fragment_task4 extends Fragment {
 | 
			
		||||
        NavController navController = Navigation.findNavController(requireView());
 | 
			
		||||
        navController.popBackStack();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroyView() {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
        handler.removeCallbacksAndMessages(null);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,34 +1,106 @@
 | 
			
		||||
package com.kolobochki.memory.ui.dashboard;
 | 
			
		||||
 | 
			
		||||
import android.app.AlertDialog;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.lifecycle.ViewModelProvider;
 | 
			
		||||
import androidx.navigation.Navigation;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.LevelRecord;
 | 
			
		||||
import com.kolobochki.memory.MainActivity;
 | 
			
		||||
import com.kolobochki.memory.databinding.FragmentDashboardBinding;
 | 
			
		||||
 | 
			
		||||
import com.kolobochki.memory.R;
 | 
			
		||||
import com.kolobochki.memory.AppDatabase;
 | 
			
		||||
import com.kolobochki.memory.GameRepository;
 | 
			
		||||
import com.kolobochki.memory.LevelRecordDao;
 | 
			
		||||
 | 
			
		||||
public class DashboardFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private FragmentDashboardBinding binding;
 | 
			
		||||
    private Executor executor = Executors.newSingleThreadExecutor();
 | 
			
		||||
    private LevelRecordDao levelRecordDao;
 | 
			
		||||
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater,
 | 
			
		||||
                             ViewGroup container, Bundle savedInstanceState) {
 | 
			
		||||
        DashboardViewModel dashboardViewModel =
 | 
			
		||||
                new ViewModelProvider(this).get(DashboardViewModel.class);
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(@Nullable Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        // Инициализация базы данных
 | 
			
		||||
        AppDatabase db = MainActivity.getDatabase();
 | 
			
		||||
        levelRecordDao = db.levelRecordDao();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 | 
			
		||||
        binding = FragmentDashboardBinding.inflate(inflater, container, false);
 | 
			
		||||
        View root = binding.getRoot();
 | 
			
		||||
 | 
			
		||||
        //final TextView textView = binding.textDashboard;
 | 
			
		||||
        //dashboardViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
 | 
			
		||||
        binding.chip.setOnClickListener(view -> {
 | 
			
		||||
            try {
 | 
			
		||||
                Navigation.findNavController(view).navigate(R.id.action_navigation_dashboard_to_navigation_info);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                //e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        binding.chip2.setOnClickListener(view -> {
 | 
			
		||||
            Navigation.findNavController(view).navigate(R.id.action_navigation_dashboard_to_navigation_records);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        binding.chip4.setOnClickListener(view -> {
 | 
			
		||||
            showResetConfirmationDialog();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        binding.chip3.setOnClickListener(view -> {
 | 
			
		||||
            new AlertDialog.Builder(requireContext())
 | 
			
		||||
                    .setTitle("Переход на другую платформу")
 | 
			
		||||
                    .setMessage("Скоро...")
 | 
			
		||||
                    .setPositiveButton("OK", null)
 | 
			
		||||
                    .show();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return root;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void showResetConfirmationDialog() {
 | 
			
		||||
        new AlertDialog.Builder(requireContext())
 | 
			
		||||
                .setTitle("Сброс статистики")
 | 
			
		||||
                .setMessage("Вы уверены, что хотите сбросить все рекорды и статистику?")
 | 
			
		||||
                .setPositiveButton("Сбросить", (dialog, which) -> resetAllStats())
 | 
			
		||||
                .setNegativeButton("Отмена", null)
 | 
			
		||||
                .show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void resetAllStats() {
 | 
			
		||||
        executor.execute(() -> {
 | 
			
		||||
            // Удаляем все записи
 | 
			
		||||
            levelRecordDao.deleteAllRecords();
 | 
			
		||||
 | 
			
		||||
            // Создаем новые пустые записи для каждого уровня
 | 
			
		||||
            for (int i = 1; i <= 4; i++) {
 | 
			
		||||
                LevelRecord record = new LevelRecord(i, 0, 0);
 | 
			
		||||
                levelRecordDao.insert(record);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Показываем уведомление в UI потоке
 | 
			
		||||
            requireActivity().runOnUiThread(() -> {
 | 
			
		||||
                Toast.makeText(requireContext(),
 | 
			
		||||
                        "Все данные сброшены", Toast.LENGTH_SHORT).show();
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroyView() {
 | 
			
		||||
        super.onDestroyView();
 | 
			
		||||
 | 
			
		||||
@ -79,4 +79,5 @@
 | 
			
		||||
        android:text="Сбросить мои данные"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@+id/imageView" />
 | 
			
		||||
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
							
								
								
									
										23
									
								
								app/src/main/res/layout/fragment_info.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/src/main/res/layout/fragment_info.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".fragment_info">
 | 
			
		||||
 | 
			
		||||
    <!-- TODO: Update blank fragment layout -->
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:text="@string/hello_blank_fragment"
 | 
			
		||||
        android:visibility="invisible" />
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/textView"
 | 
			
		||||
        android:layout_width="375dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="1. Найти пары"
 | 
			
		||||
        android:translationX="25dp"
 | 
			
		||||
        android:translationY="35dp" />
 | 
			
		||||
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
							
								
								
									
										21
									
								
								app/src/main/res/layout/fragment_records.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/src/main/res/layout/fragment_records.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    android:padding="16dp">
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="Статистика по уровням"
 | 
			
		||||
        android:textSize="20sp"
 | 
			
		||||
        android:textStyle="bold"/>
 | 
			
		||||
 | 
			
		||||
    <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/stats_recycler"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:layout_marginTop="16dp"/>
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
							
								
								
									
										36
									
								
								app/src/main/res/layout/item_level_stat.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/src/main/res/layout/item_level_stat.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="wrap_content"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    android:padding="16dp"
 | 
			
		||||
    android:background="?android:attr/selectableItemBackground"
 | 
			
		||||
    android:layout_marginBottom="8dp">
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/level_name"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:textSize="18sp"
 | 
			
		||||
        android:textStyle="bold"/>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginTop="8dp"
 | 
			
		||||
        android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/best_score"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_marginEnd="16dp"/>
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/attempts_count"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"/>
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@ -35,6 +35,12 @@
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_navigation_dashboard_to_navigation_home"
 | 
			
		||||
            app:destination="@id/navigation_home" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_navigation_dashboard_to_navigation_info"
 | 
			
		||||
            app:destination="@id/navigation_info" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_navigation_dashboard_to_navigation_records"
 | 
			
		||||
            app:destination="@id/navigation_records" />
 | 
			
		||||
    </fragment>
 | 
			
		||||
 | 
			
		||||
    <fragment
 | 
			
		||||
@ -73,4 +79,21 @@
 | 
			
		||||
            android:id="@+id/action_navigation_notifications_to_navigation_home"
 | 
			
		||||
            app:destination="@id/navigation_home" />
 | 
			
		||||
    </fragment>
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/navigation_info"
 | 
			
		||||
        android:name="com.kolobochki.memory.fragment_info"
 | 
			
		||||
        android:label="navigation_info"
 | 
			
		||||
        tools:layout="@layout/fragment_info">
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_navigation_info_to_navigation_dashboard2"
 | 
			
		||||
            app:destination="@id/navigation_dashboard" />
 | 
			
		||||
    </fragment>
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/navigation_records"
 | 
			
		||||
        android:name="com.kolobochki.memory.fragment_records"
 | 
			
		||||
        android:label="navigation_records">
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_navigation_records_to_navigation_dashboard"
 | 
			
		||||
            app:destination="@id/navigation_dashboard" />
 | 
			
		||||
    </fragment>
 | 
			
		||||
</navigation>
 | 
			
		||||
@ -10,6 +10,7 @@ lifecycleLivedataKtx = "2.8.7"
 | 
			
		||||
lifecycleViewmodelKtx = "2.8.7"
 | 
			
		||||
navigationFragment = "2.8.8"
 | 
			
		||||
navigationUi = "2.8.8"
 | 
			
		||||
roomCommonJvm = "2.7.1"
 | 
			
		||||
 | 
			
		||||
[libraries]
 | 
			
		||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
 | 
			
		||||
@ -22,6 +23,7 @@ lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-lived
 | 
			
		||||
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
 | 
			
		||||
navigation-fragment = { group = "androidx.navigation", name = "navigation-fragment", version.ref = "navigationFragment" }
 | 
			
		||||
navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigationUi" }
 | 
			
		||||
room-common-jvm = { group = "androidx.room", name = "room-common-jvm", version.ref = "roomCommonJvm" }
 | 
			
		||||
 | 
			
		||||
[plugins]
 | 
			
		||||
android-application = { id = "com.android.application", version.ref = "agp" }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user