1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.pump.activity; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.os.Bundle; 22 import android.view.LayoutInflater; 23 import android.view.Menu; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.ImageView; 27 import android.widget.TextView; 28 29 import androidx.annotation.NonNull; 30 import androidx.annotation.Nullable; 31 import androidx.annotation.UiThread; 32 import androidx.appcompat.app.ActionBar; 33 import androidx.appcompat.app.AppCompatActivity; 34 import androidx.recyclerview.widget.RecyclerView; 35 36 import com.android.pump.R; 37 import com.android.pump.db.Album; 38 import com.android.pump.db.Artist; 39 import com.android.pump.db.Audio; 40 import com.android.pump.db.MediaDb; 41 import com.android.pump.util.Globals; 42 43 @UiThread 44 public class AlbumDetailsActivity extends AppCompatActivity implements MediaDb.UpdateCallback { 45 private MediaDb mMediaDb; 46 private Album mAlbum; 47 start(@onNull Context context, @NonNull Album album)48 public static void start(@NonNull Context context, @NonNull Album album) { 49 Intent intent = new Intent(context, AlbumDetailsActivity.class); 50 // TODO(b/123704452) Pass URI instead 51 intent.putExtra("id", album.getId()); // TODO Add constant key 52 context.startActivity(intent); 53 } 54 55 @Override onCreate(@ullable Bundle savedInstanceState)56 protected void onCreate(@Nullable Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 setContentView(R.layout.activity_album_details); 59 60 setSupportActionBar(findViewById(R.id.activity_album_details_toolbar)); 61 ActionBar actionBar = getSupportActionBar(); 62 if (actionBar != null) { 63 actionBar.setDisplayShowTitleEnabled(false); 64 actionBar.setDisplayShowHomeEnabled(true); 65 actionBar.setDisplayHomeAsUpEnabled(true); 66 } 67 68 mMediaDb = Globals.getMediaDb(this); 69 mMediaDb.addAlbumUpdateCallback(this); 70 71 handleIntent(); 72 } 73 74 @Override onNewIntent(@ullable Intent intent)75 protected void onNewIntent(@Nullable Intent intent) { 76 super.onNewIntent(intent); 77 setIntent(intent); 78 79 handleIntent(); 80 } 81 82 @Override onDestroy()83 protected void onDestroy() { 84 mMediaDb.removeAlbumUpdateCallback(this); 85 86 super.onDestroy(); 87 } 88 89 @Override onCreateOptionsMenu(@onNull Menu menu)90 public boolean onCreateOptionsMenu(@NonNull Menu menu) { 91 getMenuInflater().inflate(R.menu.activity_pump, menu); // TODO activity_album_details ? 92 return true; 93 } 94 95 @Override onSupportNavigateUp()96 public boolean onSupportNavigateUp() { 97 // TODO It should not be necessary to override this method 98 onBackPressed(); 99 return true; 100 } 101 102 @Override onItemsInserted(int index, int count)103 public void onItemsInserted(int index, int count) { } 104 105 @Override onItemsUpdated(int index, int count)106 public void onItemsUpdated(int index, int count) { 107 for (int i = index; i < index + count; ++i) { 108 Album album = mMediaDb.getAlbums().get(i); 109 if (album.equals(mAlbum)) { 110 updateViews(); 111 break; 112 } 113 } 114 } 115 116 @Override onItemsRemoved(int index, int count)117 public void onItemsRemoved(int index, int count) { } 118 handleIntent()119 private void handleIntent() { 120 Intent intent = getIntent(); 121 Bundle extras = intent != null ? intent.getExtras() : null; 122 if (extras != null) { 123 long id = extras.getLong("id"); 124 125 mAlbum = mMediaDb.getAlbumById(id); 126 } else { 127 mAlbum = null; 128 // TODO This shouldn't happen -- throw exception? 129 } 130 131 mMediaDb.loadData(mAlbum); 132 updateViews(); 133 } 134 updateViews()135 private void updateViews() { 136 ImageView imageView = findViewById(R.id.activity_album_details_image); 137 TextView nameView = findViewById(R.id.activity_album_details_name); 138 TextView countView = findViewById(R.id.activity_album_details_count); 139 140 imageView.setImageURI(mAlbum.getAlbumArtUri()); 141 nameView.setText(mAlbum.getTitle()); 142 // TODO(b/123037263) I18n -- Move to resource 143 countView.setText(mAlbum.getAudios().size() + " songs"); 144 145 ImageView playView = findViewById(R.id.activity_album_details_play); 146 playView.setOnClickListener((view) -> 147 AudioPlayerActivity.start(view.getContext(), mAlbum)); 148 149 RecyclerView recyclerView = findViewById(R.id.activity_album_details_recycler_view); 150 recyclerView.setHasFixedSize(true); 151 recyclerView.setAdapter(new AlbumAdapter(mMediaDb, mAlbum)); 152 153 // TODO(b/123707260) Enable view caching 154 //recyclerView.setItemViewCacheSize(0); 155 //recyclerView.setRecycledViewPool(Globals.getRecycledViewPool(requireContext())); 156 } 157 158 private static class AlbumAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 159 private final MediaDb mMediaDb; 160 private final Album mAlbum; 161 AlbumAdapter(@onNull MediaDb mediaDb, @NonNull Album album)162 private AlbumAdapter(@NonNull MediaDb mediaDb, @NonNull Album album) { 163 setHasStableIds(true); 164 mMediaDb = mediaDb; 165 mAlbum = album; 166 } 167 168 @Override onCreateViewHolder( @onNull ViewGroup parent, int viewType)169 public @NonNull RecyclerView.ViewHolder onCreateViewHolder( 170 @NonNull ViewGroup parent, int viewType) { 171 return new AudioViewHolder(LayoutInflater.from(parent.getContext()) 172 .inflate(viewType, parent, false)); 173 } 174 175 @Override onBindViewHolder(@onNull RecyclerView.ViewHolder holder, int position)176 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { 177 Audio audio = mAlbum.getAudios().get(position); 178 mMediaDb.loadData(audio); // TODO Where should we call this? In bind()? 179 ((AudioViewHolder) holder).bind(mAlbum, audio); 180 } 181 182 @Override getItemCount()183 public int getItemCount() { 184 return mAlbum.getAudios().size(); 185 } 186 187 @Override getItemId(int position)188 public long getItemId(int position) { 189 return mAlbum.getAudios().get(position).getId(); 190 } 191 192 @Override getItemViewType(int position)193 public int getItemViewType(int position) { 194 return R.layout.audio; 195 } 196 } 197 198 private static class AudioViewHolder extends RecyclerView.ViewHolder { AudioViewHolder(@onNull View itemView)199 private AudioViewHolder(@NonNull View itemView) { 200 super(itemView); 201 } 202 bind(@onNull Album album, @NonNull Audio audio)203 private void bind(@NonNull Album album, @NonNull Audio audio) { 204 ImageView imageView = itemView.findViewById(R.id.audio_image); 205 TextView titleView = itemView.findViewById(R.id.audio_title); 206 TextView artistView = itemView.findViewById(R.id.audio_artist); 207 208 imageView.setImageURI(album.getAlbumArtUri()); 209 titleView.setText(audio.getTitle()); 210 Artist artist = audio.getArtist(); 211 artistView.setText(artist == null ? null : artist.getName()); 212 213 itemView.setOnClickListener((view) -> 214 AudioPlayerActivity.start(view.getContext(), audio)); 215 } 216 } 217 } 218