diff --git a/app/src/main/java/com/example/citrusclient/rest/ScheduleRest.java b/app/src/main/java/com/example/citrusclient/rest/ScheduleRest.java index be891fe..bfc32d4 100644 --- a/app/src/main/java/com/example/citrusclient/rest/ScheduleRest.java +++ b/app/src/main/java/com/example/citrusclient/rest/ScheduleRest.java @@ -58,6 +58,17 @@ @Query("token") String token ); + @GET(BASE_URL + "/{year}/{month}") + Call>> getScheduleByMonthAndBookId( + @Path("account_id") String accountId, + @Path("year") int year, + @Path("month") int month, + @Query("book_id") int bookId, + @Query("token") String token + ); + @GET(BASE_URL + "/{year}/{month}/{day}/{schedule_id}") Call getScheduleById( @Path("account_id") String accountId, diff --git a/app/src/main/java/com/example/citrusclient/viewmodels/BooksViewModel.java b/app/src/main/java/com/example/citrusclient/viewmodels/BooksViewModel.java index cbf3f2a..e96c043 100644 --- a/app/src/main/java/com/example/citrusclient/viewmodels/BooksViewModel.java +++ b/app/src/main/java/com/example/citrusclient/viewmodels/BooksViewModel.java @@ -20,6 +20,7 @@ private final Retrofit retrofit; private final BooksRest booksRest; private final MutableLiveData> booksLiveData; + private final MutableLiveData book; private final MutableLiveData titleLiveData; private final MutableLiveData colorLiveData; private final MutableLiveData publicityLiveData; @@ -36,12 +37,15 @@ this.colorLiveData = new MutableLiveData<>(); this.publicityLiveData = new MutableLiveData<>(); this.favoritedLiveData = new MutableLiveData<>(); + this.book = new MutableLiveData<>(); } public MutableLiveData> getBookLiveData() { return this.booksLiveData;}//本の一覧を返す public MutableLiveData getTitleLiveData() {return this.titleLiveData;}//本のタイトルを返す public MutableLiveData getPublicityLiveData() {return this.publicityLiveData;}//本の公開状態を返す + public MutableLiveData getBook() {return this.book;}; + public void createBook(String accountId, String title, String color, Boolean publicity, String token ){ Call> call = booksRest.createBook(accountId , title, color, publicity, token); @@ -84,6 +88,23 @@ }); } + public void loadBook(String accountId, String token, int bookId) { + Call call = booksRest.getBook(accountId, bookId, token); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful()) { + book.setValue(response.body()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("network error"); + } + }); + } + public void deleteBook(String accountId, Integer bookId, String token){ Call> call = booksRest.deleteBook(accountId, bookId, token); diff --git a/app/src/main/java/com/example/citrusclient/viewmodels/ScheduleViewModel.java b/app/src/main/java/com/example/citrusclient/viewmodels/ScheduleViewModel.java index 700826f..f793ff9 100644 --- a/app/src/main/java/com/example/citrusclient/viewmodels/ScheduleViewModel.java +++ b/app/src/main/java/com/example/citrusclient/viewmodels/ScheduleViewModel.java @@ -193,6 +193,34 @@ }); } + /** + * アカウントと年と月を指定してschedulesByMonthを更新する + * + * @param accountId アカウントid + * @param year 年 + * @param month 月 + * @param token トークン + * @param bookId ほんのid + */ + public void updateSchedulesByMonthAndBookId(String accountId, int year, int month, String token, int bookId){ + Call>> call = scheduleRest.getScheduleByMonthAndBookId(accountId, year, month, bookId, token); + call.enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, Response>> response) { + if(response.isSuccessful()){ + schedulesByMonth.setValue(response.body()); + } else { + schedulesByMonth.setValue(new HashMap<>()); + errorLiveData.setValue(response.message()); + } + } + @Override + public void onFailure(Call>> call, Throwable t) { + errorLiveData.setValue(t.getMessage()); + } + }); + } + /** * アカウントと年と月と日を指定してスケジュールを更新する diff --git a/app/src/main/java/com/example/citrusclient/views/MyAdapter.java b/app/src/main/java/com/example/citrusclient/views/MyAdapter.java new file mode 100644 index 0000000..2811bd6 --- /dev/null +++ b/app/src/main/java/com/example/citrusclient/views/MyAdapter.java @@ -0,0 +1,194 @@ +//package com.example.citrusclient.views; +// +//import android.view.LayoutInflater; +//import android.view.View; +//import android.view.ViewGroup; +//import android.widget.TextView; +// +//import androidx.recyclerview.widget.RecyclerView; +// +//import com.example.citrusclient.R; +//import com.example.citrusclient.models.Book; +// +//import java.util.ArrayList; +//import java.util.List; +// +//public class MyAdapter extends RecyclerView.Adapter { +// private List originalList; // 元のデータリスト +// private List filteredList; +// +// public MyAdapter(List originalList) { +// this.originalList = originalList; +// this.filteredList = new ArrayList<>(originalList); +// } +// +// @Override +// public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { +// View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.a_public_book, parent, false); +// return new ViewHolder(view); +// } +// +// @Override +// public void onBindViewHolder(ViewHolder holder, int position) { +// Book currentBook = filteredList.get(position); +// holder.bind(currentBook); +// } +// +// @Override +// public int getItemCount() { +// return filteredList.size(); +// } +// +// public void filter(String query) { +// filteredList.clear(); +// if (query.isEmpty()) { +// filteredList.addAll(originalList); +// } else { +// String[] queryWords = query.toLowerCase().trim().split("\\s+"); +// for (Book item : originalList) { +// boolean matchesAll = true; +// for (String word : queryWords) { +// if (!item.getAccountId().toLowerCase().contains(word)) { +// matchesAll = false; +// break; +// } +// } +// if (matchesAll) { +// filteredList.add(item); +// } +// } +// } +// notifyDataSetChanged(); +// } +// +// public void setBooks(ArrayList publicList) { +// } +// +// static class ViewHolder extends RecyclerView.ViewHolder { +// TextView titleTextView; +// TextView authorTextView; +// +// ViewHolder(View itemView) { +// super(itemView); +// titleTextView = itemView.findViewById(R.id.public_button); +// authorTextView = itemView.findViewById(R.id.public_id); +// } +// +// void bind(Book book) { +// titleTextView.setText(book.getTitle()); +// authorTextView.setText(book.getAccountId()); +// } +// } +//} + +package com.example.citrusclient.views; + +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.example.citrusclient.R; +import com.example.citrusclient.models.Book; + +import java.util.ArrayList; +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +public class MyAdapter extends RecyclerView.Adapter { + private List originalList; // 元のデータリスト + private List filteredList; // フィルタリングされたリスト + private Object context; + +// private List publicList; +// private List accountIdList; +// private Context context; + + public MyAdapter(List originalList) { + this.originalList = originalList; + this.filteredList = new ArrayList<>(originalList); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.a_public_book, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Book currentBook = filteredList.get(position); + holder.bind(currentBook); // bindメソッドで設定 + + // 背景色の設定 + int red, green, blue; + if (currentBook.getColor() == null || currentBook.getColor().length() < 7) { + red = 255; green = 255; blue = 255; + } else { + red = Integer.parseInt(currentBook.getColor().substring(1, 3), 16); + green = Integer.parseInt(currentBook.getColor().substring(3, 5), 16); + blue = Integer.parseInt(currentBook.getColor().substring(5, 7), 16); + } + holder.titleTextView.setBackgroundColor(Color.rgb(red, green, blue)); + holder.titleTextView.setTextColor(Color.rgb(255 - red, 255 - green, 255 - blue)); +// holder.titleTextView.setOnClickListener(v -> { +// Activity activity = (Activity) context; +// Citrus citrus = (Citrus) activity.getApplication(); +// citrus.setCurLookingAccountId(currentBook.getAccountId()); +// citrus.setCurLookingBookId(currentBook.getBookId()); +// ((MainActivity) activity).showFragment(new HomeFragment()); +// }); + } + + @Override + public int getItemCount() { + return filteredList.size(); + } + + // 新しいデータを設定するメソッド + public void setBooks(List books) { + originalList.clear(); + originalList.addAll(books); + filteredList.clear(); // フィルタリングされたリストもクリア + filteredList.addAll(originalList); // 元のリストの内容を追加 + notifyDataSetChanged(); // アダプターを更新 + } + + // フィルタリングメソッド + public void filter(String query) { + filteredList.clear(); + if (query.isEmpty()) { + filteredList.addAll(originalList); + } else { + String lowerCaseQuery = query.toLowerCase().trim(); + for (Book item : originalList) { + if (item.getAccountId().toLowerCase().contains(lowerCaseQuery) || + item.getTitle().toLowerCase().contains(lowerCaseQuery)) { + filteredList.add(item); + } + } + } + notifyDataSetChanged(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + TextView titleTextView; + TextView authorTextView; + + ViewHolder(View itemView) { + super(itemView); + titleTextView = itemView.findViewById(R.id.public_button); + authorTextView = itemView.findViewById(R.id.public_id); + + } + + void bind(Book book) { + titleTextView.setText(book.getTitle()); + authorTextView.setText(book.getAccountId()); + } + } +} diff --git a/app/src/main/java/com/example/citrusclient/views/SearchFragment.java b/app/src/main/java/com/example/citrusclient/views/SearchFragment.java index 41509ac..dddb7e8 100644 --- a/app/src/main/java/com/example/citrusclient/views/SearchFragment.java +++ b/app/src/main/java/com/example/citrusclient/views/SearchFragment.java @@ -1,11 +1,13 @@ package com.example.citrusclient.views; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import androidx.annotation.NonNull; +import androidx.core.view.MenuItemCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Observer; @@ -13,11 +15,16 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.text.Editable; +import android.util.Log; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.SearchView; import android.widget.TextView; import com.example.citrusclient.Citrus; @@ -49,6 +56,18 @@ // Required empty public constructor } + private static final String TAG = SearchFragment.class.getSimpleName(); + private final SearchFragment self = this; + + private SearchView searchView; + private String searchWord; + + private Integer sortBy = 0; + + EditText editText; + + private MyAdapter adapter; + /** * Use this factory method to create a new instance of * this fragment using the provided parameters. @@ -89,37 +108,79 @@ return inflater.inflate(R.layout.fragment_search, container, false); } + @SuppressLint("WrongViewCast") public void onViewCreated(@NonNull View view, @NonNull Bundle saveInstanceState){ super.onViewCreated(view, saveInstanceState); -// LinearLayout layout = new LinearLayout(requireContext()); -// Citrus citrus = (Citrus)(getActivity().getApplication()); - publicList = new ArrayList<>(); - name = new ArrayList<>(); - + adapter = new MyAdapter(new ArrayList<>()); RecyclerView recyclerView = view.findViewById(R.id.public_list); - recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext())); - RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(view.getContext()); - recyclerView.setLayoutManager(layoutManager); - PublicAdapter publicAdapter = new PublicAdapter(name, publicList, getActivity()); - recyclerView.setAdapter(publicAdapter); + recyclerView.setAdapter(adapter); +// RecyclerView recyclerView1 = view.findViewById(R.id.sort_by); +// recyclerView1.setLayoutManager(new LinearLayoutManager(view.getContext())); +// recyclerView1.setAdapter(adapter); + publicBooksViewModel.getAllBooksLiveData().observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(ArrayList books) { - if(books != null){ - for(int i = 0; i < books.size(); i++){ - name.add(books.get(i).getAccountId()); - } + if (books != null) { publicList = new ArrayList<>(books); - }else{ - publicList = new ArrayList<>(); + adapter.setBooks(publicList); // アダプターに新しいリストを渡す } - publicAdapter.setBooks(publicList); - System.out.println(name); } }); + publicBooksViewModel.loadAllBooks(); + + SearchView searchView = view.findViewById(R.id.search_word); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + loadSearchResults(query); + Log.d(TAG, "Search query: " + query); + return true; + } + + @Override +// public boolean onQueryTextChange(String newText) { +// //adapter.filter(newText); // フィルタリングを実行 +// loadSearchResults(newText); +// System.out.println("ahe"); +// return true; +//} + public boolean onQueryTextChange(String newText) { + adapter.filter(newText); // フィルタリングを実行 + return true; + } + + }); + } + + private void loadSearchResults(String query) { + // 空白で分割 + String[] parts = query.split(" "); + String title = parts.length > 0 ? parts[0] : ""; // 最初の部分をtitleに + String accountId = parts.length > 1 ? parts[1] : ""; // 2番目の部分をaccountIdに + Integer sortBy = 1; + //if(sortBy != null) sortBy = sort;//ソートはまだ + Log.d(TAG, "Search query: " + title + accountId); + + if(title != null) { + if (accountId != null) { + publicBooksViewModel.loadSearchBooks(title, accountId, sortBy);//title,accountidでの検索 + if(accountId == null)accountId = "null"; + if(accountId == "")accountId = "space"; + System.out.println("title: "+title+" accountId: "+accountId+" sortBy: "+sortBy); + }/* else { + publicBooksViewModel.loadSearchTitleBooks(title, sortBy);//titleのみの検索 + } + if (accountId != null) { + publicBooksViewModel.loadSearchAccountIdBooks(accountId, sortBy);//accountidでの検索 + } */else { + publicBooksViewModel.loadAllBooks(); + } + // titleとaccountIdを使って検索 + } } } @@ -154,14 +215,9 @@ holder.idText.setWidth(100); Book publicData = this.publicList.get(position); holder.publicButton.setText(publicData.getTitle()); - int red; - int green; - int blue; - if (publicData.getColor() == null) { - red = 255; - green = 255; - blue = 255; - } else if (publicData.getColor().length() < 7) { + + int red, green, blue; + if (publicData.getColor() == null || publicData.getColor().length() < 7) { red = 255; green = 255; blue = 255; @@ -201,10 +257,4 @@ idText = itemView.findViewById(R.id.public_id); } } -} - - -/*recyclerviewの中にrecyclerviewを入れよう(縦スクに横スクをいれる感じ) -linearlayoutを縦にいれる - - */ \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index 2b8dec3..69464fe 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -7,6 +7,7 @@ tools:context=".views.SearchFragment"> + + android:id="@+id/search_word" + android:layout_width="300dp" + android:layout_height="80dp" + android:layout_marginTop="60dp" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginTop="140dp"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 6090f93..d5faa25 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -13,19 +13,6 @@ android:layout_height="match_parent"> - - + app:layout_constraintVertical_bias="0.333" /> - + app:layout_constraintVertical_bias="0.068" /> +