diff --git a/Singers/app/build.gradle b/Singers/app/build.gradle index 4802075..023e7f6 100644 --- a/Singers/app/build.gradle +++ b/Singers/app/build.gradle @@ -22,6 +22,12 @@ android { repositories { mavenCentral() } +configurations.all { + resolutionStrategy.force 'com.android.support:support-annotations:22.1.0' +} +apply plugin: 'com.android.application' +apply plugin: 'android-apt' + dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' @@ -35,6 +41,10 @@ dependencies { compile 'com.nhaarman.listviewanimations:lib-core-slh:3.1.0@aar' compile 'com.nineoldandroids:library:2.4.0' + //butterknife + compile 'com.jakewharton:butterknife:8.2.1' + apt 'com.jakewharton:butterknife-compiler:8.2.1' + androidTestCompile 'com.android.support.test:runner:0.4.1' androidTestCompile 'com.android.support.test:rules:0.4.1' // Optional -- Hamcrest library @@ -43,4 +53,6 @@ dependencies { androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' // Optional -- UI testing with UI Automator androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' + + } diff --git a/Singers/app/src/main/AndroidManifest.xml b/Singers/app/src/main/AndroidManifest.xml index 1d2d0f1..f659883 100644 --- a/Singers/app/src/main/AndroidManifest.xml +++ b/Singers/app/src/main/AndroidManifest.xml @@ -16,34 +16,22 @@ android:resource="@xml/searchable" /> + + + + - - - - - - - - - - diff --git a/Singers/app/src/main/java/ru/daria/singers/AboutProgramDialog.java b/Singers/app/src/main/java/ru/daria/singers/AboutProgramDialog.java new file mode 100644 index 0000000..6d48111 --- /dev/null +++ b/Singers/app/src/main/java/ru/daria/singers/AboutProgramDialog.java @@ -0,0 +1,28 @@ +package ru.daria.singers; + +import android.app.DialogFragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import butterknife.ButterKnife; + +/** + * Created by dsukmanova on 17.07.16. + */ +public class AboutProgramDialog extends DialogFragment { + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance){ + View view = inflater.inflate(R.layout.about_program, null); + ButterKnife.findById(view,R.id.okButton).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getDialog().dismiss(); + } + }); + getDialog().setTitle(R.string.aboutTitle); + return view; + } + +} diff --git a/Singers/app/src/main/java/ru/daria/singers/HomeActivity.java b/Singers/app/src/main/java/ru/daria/singers/DataLoader.java similarity index 53% rename from Singers/app/src/main/java/ru/daria/singers/HomeActivity.java rename to Singers/app/src/main/java/ru/daria/singers/DataLoader.java index a5984d2..a19be6a 100644 --- a/Singers/app/src/main/java/ru/daria/singers/HomeActivity.java +++ b/Singers/app/src/main/java/ru/daria/singers/DataLoader.java @@ -1,60 +1,88 @@ package ru.daria.singers; -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; +import android.content.AsyncTaskLoader; +import android.content.Context; import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.TextView; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.io.Serializable; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** - * Activity для отображения окна приветствия, загрузки списка исполнителей + * Created by dsukmanova on 17.07.16. */ -public class HomeActivity extends Activity { - List singers = new ArrayList(); +public class DataLoader extends AsyncTaskLoader>> { + private final String URLSingers = "http://cache-default06g.cdn.yandex.net/download.cdn.yandex.net/mobilization-2016/artists.json"; + private HttpURLConnection urlConnection = null; + private DataLoaderResult> result; + + public DataLoader(Context context) { + super(context); + } @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.splash); - Extractor ex = new Extractor(new Extractor.AsyncResponse() { - @Override - public void processFinish(String output) { - try { - JSONArray dataJson = new JSONArray(output); - singers = getSingersFromJson(dataJson); - Intent i = new Intent(HomeActivity.this, MainActivity.class); - i.putExtra("SINGERS", (Serializable) singers); - startActivity(i); - finish(); - } catch (JSONException ex) { - ex.printStackTrace(); - Button b = (Button) findViewById(R.id.tryAgainButton); - b.setVisibility(View.VISIBLE); - TextView v = (TextView) findViewById(R.id.splashText); - v.setText("Невозможно загрузить список исполнителей."); - } - } - }); - ex.execute(); + protected void onStartLoading() { + super.onStartLoading(); + if (result != null) { + deliverResult(result); + } else { + forceLoad(); + } + } + + @Override + public void deliverResult(DataLoaderResult> result) { + this.result = result; + super.deliverResult(result); } - public void buttonOnClick(View view) { - Button b = (Button) findViewById(R.id.tryAgainButton); - b.setVisibility(View.INVISIBLE); - Intent i = new Intent(HomeActivity.this, HomeActivity.class); - startActivity(i); + @Override + public DataLoaderResult> loadInBackground() { + DataLoaderResult> result = new DataLoaderResult>(); + try { + URL url = new URL(URLSingers); + urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setRequestMethod("GET"); + urlConnection.connect(); + + InputStream inputStream = urlConnection.getInputStream(); + StringBuilder buffer = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + while ((line = reader.readLine()) != null) { + buffer.append(line); + } + String resultJson = buffer.toString(); + JSONArray dataJson = new JSONArray(resultJson); + List singers = getSingersFromJson(dataJson); + result.setResult(singers); + } catch (MalformedURLException ex) { + Log.e("ERROR", "URL is not available"); + result.setException(ex); + } catch (IOException ex) { + Log.e("ERROR", "Cannot open url connection."); + result.setException(ex); + } catch (JSONException ex) { + Log.e("ERROR", "Problems with JSON"); + result.setException(ex); + } finally { + if (urlConnection != null) { + urlConnection.disconnect(); + } + } + return result; } /** @@ -109,5 +137,4 @@ public List getSingersFromJson(JSONArray jSingers) { } return singers; } - } diff --git a/Singers/app/src/main/java/ru/daria/singers/DataLoaderResult.java b/Singers/app/src/main/java/ru/daria/singers/DataLoaderResult.java new file mode 100644 index 0000000..1678ceb --- /dev/null +++ b/Singers/app/src/main/java/ru/daria/singers/DataLoaderResult.java @@ -0,0 +1,27 @@ +package ru.daria.singers; + +/** + * Created by dsukmanova on 24.07.16. + */ + +public class DataLoaderResult { + private Exception exception; + private T result; + + public void setException(Exception exception) { + this.exception = exception; + } + + public void setResult(T result) { + this.result = result; + } + + public Exception getException() { + + return exception; + } + + public T getResult() { + return result; + } +} diff --git a/Singers/app/src/main/java/ru/daria/singers/DetailsActivity.java b/Singers/app/src/main/java/ru/daria/singers/DetailsFragment.java similarity index 60% rename from Singers/app/src/main/java/ru/daria/singers/DetailsActivity.java rename to Singers/app/src/main/java/ru/daria/singers/DetailsFragment.java index 89bf338..31f6b16 100644 --- a/Singers/app/src/main/java/ru/daria/singers/DetailsActivity.java +++ b/Singers/app/src/main/java/ru/daria/singers/DetailsFragment.java @@ -1,12 +1,12 @@ package ru.daria.singers; -import android.content.Intent; +import android.app.Fragment; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; -import android.view.Menu; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; @@ -14,45 +14,57 @@ import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; -public class DetailsActivity extends AppCompatActivity { - //настройка кэширования изображений +import butterknife.BindView; +import butterknife.ButterKnife; + +/** + * Created by dsukmanova on 16.07.16. + */ +public class DetailsFragment extends Fragment { private static DisplayImageOptions options = new DisplayImageOptions.Builder(). cacheInMemory(true).cacheOnDisk(true).build(); - private String albumsDescr; @Override - protected void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.details); + //ButterKnife.bind(this); + } - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + @Override + public View onCreateView(LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.details, container, false); + final MainActivity activity = (MainActivity) getActivity(); + + Toolbar toolbar = activity.getToolbar(); toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha); + activity.showMenuVisible(toolbar.getMenu(), false); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //действие аналогично стандартной кнопке "Назад" - onBackPressed(); + activity.onBackPressed(); } }); - ImageView image = (ImageView) findViewById(R.id.image); - TextView description = (TextView) findViewById(R.id.descriprion); - TextView genres = (TextView) findViewById(R.id.genres); - TextView albums = (TextView) findViewById(R.id.albums); + ImageView image = ButterKnife.findById(view, R.id.image); + TextView description = ButterKnife.findById(view, R.id.descriprion); + TextView genres = ButterKnife.findById(view, R.id.genres); + TextView albums = ButterKnife.findById(view, R.id.albums); //получаем экземпляр Singer из MainActivity - Intent intent = getIntent(); - Bundle b = intent.getExtras(); + Bundle b = getArguments(); Singer singer = (Singer) b.get("SINGER"); toolbar.setTitle(singer.getName()); //пока подгружается изображение показываем стандартное String uri = "@drawable/defaultimage"; - int imageResource = getResources().getIdentifier(uri, null, getPackageName()); + int imageResource = getResources().getIdentifier(uri, null, activity.getPackageName()); Drawable res = getResources().getDrawable(imageResource); image.setImageDrawable(res); //Конфигурация для ImageLoader - ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build(); + ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(activity).build(); final ImageLoader imageLoader = ImageLoader.getInstance(); imageLoader.init(config); @@ -63,20 +75,13 @@ public void onClick(View v) { description.setText(singer.getDescription()); genres.setText(singer.genresToString()); int albumsNum = singer.getAlbums(); - String[] albumCases = {"альбом", "альбома", "альбомов"}; int tracksNum = singer.getTracks(); - String[] trackCases = {"песня", "песни", "песен"}; //склоняем альбомы и песни - String albumsDescr = "%d %s • %d %s"; - albumsDescr = String.format(albumsDescr, albumsNum, singer.getEnding(albumsNum, albumCases), - tracksNum, singer.getEnding(tracksNum, trackCases)); + String albumsDescr = "%s • %s"; + albumsDescr = String.format(albumsDescr, + getResources().getQuantityString(R.plurals.songs, albumsNum, albumsNum), + getResources().getQuantityString(R.plurals.tracks, tracksNum, tracksNum)); albums.setText(albumsDescr); - + return view; } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return super.onCreateOptionsMenu(menu); - } - } diff --git a/Singers/app/src/main/java/ru/daria/singers/Extractor.java b/Singers/app/src/main/java/ru/daria/singers/Extractor.java deleted file mode 100644 index 84b4d71..0000000 --- a/Singers/app/src/main/java/ru/daria/singers/Extractor.java +++ /dev/null @@ -1,72 +0,0 @@ -package ru.daria.singers; - -import android.os.AsyncTask; -import android.util.Log; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - - -/** - * Извлечение Json по URL - */ -public class Extractor extends AsyncTask { - private final String URLSingers = "http://cache-default06g.cdn.yandex.net/download.cdn.yandex.net/mobilization-2016/artists.json"; - private HttpURLConnection urlConnection = null; - private String resultJson = ""; - - public AsyncResponse delegate = null; - - public interface AsyncResponse { - /** - * Вызывается по окончании извлечения данных из json - */ - void processFinish(String output); - } - - public Extractor(AsyncResponse delegate) { - this.delegate = delegate; - } - - @Override - protected String doInBackground(Void... params) { - // получаем данные с внешнего ресурса - try { - URL url = new URL(URLSingers); - urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setRequestMethod("GET"); - urlConnection.connect(); - - InputStream inputStream = urlConnection.getInputStream(); - StringBuilder buffer = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - String line; - while ((line = reader.readLine()) != null) { - buffer.append(line); - } - - resultJson = buffer.toString(); - } catch (MalformedURLException e) { - Log.e("ERROR", "URL is not available"); - } catch (IOException ex) { - Log.e("ERROR", "Cannot open url connection."); - } finally { - if (urlConnection != null) { - urlConnection.disconnect(); - } - } - return resultJson; - } - - @Override - protected void onPostExecute(String strJson) { - super.onPostExecute(strJson); - delegate.processFinish(strJson); - } - -} \ No newline at end of file diff --git a/Singers/app/src/main/java/ru/daria/singers/ListItemAdapter.java b/Singers/app/src/main/java/ru/daria/singers/ListItemAdapter.java index 3357517..2796fd6 100644 --- a/Singers/app/src/main/java/ru/daria/singers/ListItemAdapter.java +++ b/Singers/app/src/main/java/ru/daria/singers/ListItemAdapter.java @@ -17,7 +17,11 @@ import java.util.ArrayList; import java.util.List; +import butterknife.BindView; +import butterknife.ButterKnife; + public class ListItemAdapter extends BaseAdapter implements Filterable { + private Context context; private final ImageLoader imageLoader; private LayoutInflater lInflater; private List singers; @@ -28,18 +32,12 @@ public class ListItemAdapter extends BaseAdapter implements Filterable { private static DisplayImageOptions options = new DisplayImageOptions.Builder(). cacheInMemory(true).cacheOnDisk(true).build(); - static class ViewHolder { - public ImageView imageView; - public TextView name; - public TextView styles; - public TextView description; - } - public ListItemAdapter(Activity context, List singers, ImageLoader imageLoader, View.OnClickListener callback ) { + this.context = context; this.singers = singers; this.filteredSingers = singers; this.imageLoader = imageLoader; @@ -47,6 +45,21 @@ public ListItemAdapter(Activity context, this.callback = callback; } + static class ViewHolder { + @BindView(R.id.image) + ImageView image; + @BindView(R.id.singer) + TextView name; + @BindView(R.id.styles) + TextView styles; + @BindView(R.id.albums) + TextView description; + + public ViewHolder(View view) { + ButterKnife.bind(this, view); + } + } + @Override public int getCount() { return filteredSingers.size(); @@ -76,11 +89,7 @@ public View getView(int position, View convertView, ViewGroup parent) { //используем созданные ранее View, но уже не используемые if (view == null) { view = lInflater.inflate(R.layout.list_single, parent, false); - holder = new ViewHolder(); - holder.imageView = (ImageView) view.findViewById(R.id.image); - holder.name = (TextView) view.findViewById(R.id.singer); - holder.styles = (TextView) view.findViewById(R.id.styles); - holder.description = (TextView) view.findViewById(R.id.albums); + holder = new ViewHolder(view); view.setClickable(true); view.setOnClickListener(callback); view.setTag(holder); @@ -90,9 +99,9 @@ public View getView(int position, View convertView, ViewGroup parent) { Singer singer = getSinger(position); //заполняем View данными //пока не подгрузилась картинка показываем дефолтную - holder.imageView.setImageResource(R.drawable.defaultimage); + holder.image.setImageResource(R.drawable.defaultimage); if (singer.getCovers() != null) { - imageLoader.displayImage(singer.getCovers().get(Singer.coverTypes.small), holder.imageView, options); + imageLoader.displayImage(singer.getCovers().get(Singer.coverTypes.small), holder.image, options); } holder.name.setText(singer.getName()); holder.styles.setText(singer.genresToString()); @@ -102,9 +111,10 @@ public View getView(int position, View convertView, ViewGroup parent) { String[] trackCases = {"песня", "песни", "песен"}; //склоняем альбомы и песни - String albumsDescr = "%d %s • %d %s"; - albumsDescr = String.format(albumsDescr, albumsNum, singer.getEnding(albumsNum, albumCases), - tracksNum, singer.getEnding(tracksNum, trackCases)); + String albumsDescr = "%s • %s"; + albumsDescr = String.format(albumsDescr, + context.getResources().getQuantityString(R.plurals.songs, albumsNum, albumsNum), + context.getResources().getQuantityString(R.plurals.tracks, tracksNum, tracksNum)); holder.description.setText(albumsDescr); return view; } @@ -144,4 +154,13 @@ protected void publishResults(CharSequence charSequence, FilterResults filterRes }; } + + public List getSingers(){ + return singers; + } + + public void setSingers(List singers){ + this.singers.clear(); + this.singers.addAll(singers); + } } diff --git a/Singers/app/src/main/java/ru/daria/singers/MainActivity.java b/Singers/app/src/main/java/ru/daria/singers/MainActivity.java index 707c792..a72aced 100644 --- a/Singers/app/src/main/java/ru/daria/singers/MainActivity.java +++ b/Singers/app/src/main/java/ru/daria/singers/MainActivity.java @@ -1,9 +1,15 @@ package ru.daria.singers; +import android.app.FragmentManager; +import android.app.FragmentTransaction; import android.app.SearchManager; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Resources; +import android.net.Uri; import android.os.Bundle; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AppCompatActivity; @@ -11,56 +17,38 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; -import android.widget.ListView; import android.support.v7.widget.SearchView; -import com.nhaarman.listviewanimations.appearance.simple.SwingRightInAnimationAdapter; -import com.nostra13.universalimageloader.core.*; - import java.util.ArrayList; import java.util.List; -public class MainActivity extends AppCompatActivity implements View.OnClickListener { +import butterknife.BindView; +import butterknife.ButterKnife; + +public class MainActivity extends AppCompatActivity implements MainFragment.OnSingerSelectedListener { List singers = new ArrayList<>(); - ListItemAdapter adapter; + HeadsetPlugReceiver headsetPlugReceiver; + @BindView(R.id.toolbar) + Toolbar toolbar; + private FragmentManager fm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - // Конфигурация для ImageLoader - ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build(); - final ImageLoader imageLoader = ImageLoader.getInstance(); - imageLoader.init(config); - setContentView(R.layout.activity_main); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - - Intent intent = getIntent(); - //получаем список исполнителей из HomeActivity - singers = (List) intent.getSerializableExtra("SINGERS"); - - adapter = new ListItemAdapter(MainActivity.this, singers, imageLoader, MainActivity.this); - - //анимация при пролистывании списка исполнителей - final SwingRightInAnimationAdapter rightInAnimationAdapter = new SwingRightInAnimationAdapter(adapter); - - ListView mainList = (ListView) findViewById(R.id.listView); - rightInAnimationAdapter.setAbsListView(mainList); - mainList.setAdapter(rightInAnimationAdapter); - mainList.setTextFilterEnabled(true); + ButterKnife.bind(this); + if (savedInstanceState == null) { + fm = getFragmentManager(); + FragmentTransaction fragmentTransaction = fm.beginTransaction(); + MainFragment fragment = new MainFragment(); + fragmentTransaction.add(R.id.fragmentContainer, fragment); + fragmentTransaction.commit(); + } } - //Действие по нажатию строки в ListView с исполнителями - @Override - public void onClick(View view) { - int position = ((ListView) view.getParent()).getPositionForView(view); - Singer singer = adapter.getSinger(position); - Intent info = new Intent(this, DetailsActivity.class); - info.putExtra("SINGER", singer); - startActivity(info); + private ListItemAdapter getListAdapter() { + MainFragment currFragment = (MainFragment) getFm().findFragmentById(R.id.fragmentContainer); + return currFragment.adapter; } @Override @@ -81,24 +69,138 @@ public boolean onCreateOptionsMenu(Menu menu) { @Override public boolean onQueryTextSubmit(String query) { //при подтверждении текста поиска - adapter.getFilter().filter(query); + getListAdapter().getFilter().filter(query); return true; } @Override public boolean onQueryTextChange(String newText) { //при изменении текста поиска - adapter.getFilter().filter(newText); + getListAdapter().getFilter().filter(newText); return true; } }; searchView.setOnQueryTextListener(textChangeListener); + return super.onCreateOptionsMenu(menu); } + public void showMenuVisible(Menu menu, boolean showMenu) { + if (menu == null) return; + menu.setGroupVisible(R.id.main_menu_group, showMenu); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.about: + onAboutProgramItemSelected(); + break; + case R.id.feedback: + onFeedbackItemSelected(); + break; + default: + break; + } return super.onOptionsItemSelected(item); + + } + + private void onAboutProgramItemSelected() { + FragmentManager fragmentManager = getFm(); + AboutProgramDialog aboutProgramDialog = new AboutProgramDialog(); + aboutProgramDialog.show(fragmentManager, "О программе"); + } + + private void onFeedbackItemSelected() { + Intent intent = new Intent(Intent.ACTION_SENDTO); + Resources recources = getResources(); + String uriText = String.format("mailto:%s ?subject= %s &body=%s", + recources.getString(R.string.contactEmail), + recources.getString(R.string.feedbackSubj), + recources.getString(R.string.feedbackText)); + Uri uri = Uri.parse(uriText); + intent.setData(uri); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Intent mailer = Intent.createChooser(intent, "Напишите нам..."); + startActivity(mailer); + } + + @Override + public void onBackPressed() { + if (getFm().getBackStackEntryCount() == 0) { + this.finish(); + } else { + getFm().popBackStack(); + toolbar.setNavigationIcon(null); + toolbar.setTitle(R.string.title_activity_main); + showMenuVisible(toolbar.getMenu(), true); + } } + @Override + public void onSingerSelected(Singer singer) { + DetailsFragment fragment = new DetailsFragment(); + Bundle arg = new Bundle(); + arg.putSerializable("SINGER", singer); + fragment.setArguments(arg); + FragmentManager fragmentManager = getFm(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.replace(R.id.fragmentContainer, fragment); + fragmentTransaction.addToBackStack(null); + fragmentTransaction.commit(); + } + + @Override + protected void onResume() { + super.onResume(); + this.headsetPlugReceiver = new HeadsetPlugReceiver(); + registerReceiver(this.headsetPlugReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); + } + + @Override + protected void onPause() { + unregisterReceiver(headsetPlugReceiver); + super.onPause(); + } + + private void showMusicDialog() { + MusicDialog musicDialog = new MusicDialog(); + musicDialog.show(getFm(), null); + } + + public class HeadsetPlugReceiver extends BroadcastReceiver { + private boolean headsetEnabled = true; + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) { + int state = intent.getIntExtra("state", -1); + switch (state) { + case 1: + //headset_plugged + if (headsetEnabled == false) { + headsetEnabled = true; + showMusicDialog(); + } + break; + case 0: + headsetEnabled = false; + break; + default: + break; + } + } + } + } + + public Toolbar getToolbar() { + return toolbar; + } + + public FragmentManager getFm() { + return fm; + } + + } \ No newline at end of file diff --git a/Singers/app/src/main/java/ru/daria/singers/MainFragment.java b/Singers/app/src/main/java/ru/daria/singers/MainFragment.java new file mode 100644 index 0000000..34021fc --- /dev/null +++ b/Singers/app/src/main/java/ru/daria/singers/MainFragment.java @@ -0,0 +1,125 @@ +package ru.daria.singers; + +import android.app.Activity; +import android.app.Fragment; +import android.app.LoaderManager; +import android.content.Loader; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import android.widget.ProgressBar; + +import com.nhaarman.listviewanimations.appearance.simple.SwingRightInAnimationAdapter; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import butterknife.ButterKnife; + +/** + * Created by dsukmanova on 15.07.16. + */ +public class MainFragment extends Fragment implements View.OnClickListener, LoaderManager.LoaderCallbacks>> { + List singers = new ArrayList<>(); + ListItemAdapter adapter; + OnSingerSelectedListener mListener; + final int LOADER_ID = 0; + + public interface OnSingerSelectedListener { + void onSingerSelected(Singer singer); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + Loader loader = getLoaderManager().initLoader(LOADER_ID, null, this); + loader.forceLoad(); + } + + @Override + public Loader>> onCreateLoader(int id, Bundle args) { + DataLoader loader = new DataLoader(getActivity()); + return loader; + } + + @Override + public void onLoadFinished(Loader>> loader, DataLoaderResult> data) { + Exception ex = data.getException(); + if (ex != null) { + ex.printStackTrace(); + if (ex instanceof IOException) { + /*Button b = ButterKnife.findById(view, R.id.tryAgainButton); + b.setVisibility(View.VISIBLE); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Button b = (Button) v; + b.setVisibility(View.INVISIBLE); + getLoaderManager().restartLoader(LOADER_ID, null, HomeFragment.this); + } + }); + TextView v = ButterKnife.findById(view, R.id.splashText); + v.setText("Невозможно загрузить список исполнителей.");*/ + ex.printStackTrace(); + } + } else { + singers = data.getResult(); + adapter.setSingers(singers); + adapter.notifyDataSetChanged(); + } + } + + @Override + public void onLoaderReset(Loader>> loader) { + + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + mListener = (OnSingerSelectedListener) getActivity(); + } catch (ClassCastException ex) { + throw new ClassCastException(getActivity().toString() + "must implement OnSingerSelectedListener"); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.content_main, container, false); + Activity activity = getActivity(); + + ((AppCompatActivity) activity).setSupportActionBar(((MainActivity)activity).getToolbar()); + + // Конфигурация для ImageLoader + ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity()).build(); + final ImageLoader imageLoader = ImageLoader.getInstance(); + imageLoader.init(config); + + adapter = new ListItemAdapter(activity, singers, imageLoader, this); + + final SwingRightInAnimationAdapter rightInAnimationAdapter = new SwingRightInAnimationAdapter(adapter); + ListView mainList = ButterKnife.findById(view,R.id.listView); + rightInAnimationAdapter.setAbsListView(mainList); + mainList.setAdapter(rightInAnimationAdapter); + mainList.setTextFilterEnabled(true); + + return view; + } + + @Override + public void onClick(View view) { + int position = ((ListView) view.getParent()).getPositionForView(view); + Singer singer = adapter.getSinger(position); + mListener.onSingerSelected(singer); + } +} diff --git a/Singers/app/src/main/java/ru/daria/singers/MusicDialog.java b/Singers/app/src/main/java/ru/daria/singers/MusicDialog.java new file mode 100644 index 0000000..3d87712 --- /dev/null +++ b/Singers/app/src/main/java/ru/daria/singers/MusicDialog.java @@ -0,0 +1,71 @@ +package ru.daria.singers; + +import android.app.DialogFragment; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import butterknife.ButterKnife; + +/** + * Created by dsukmanova on 18.07.16. + */ +public class MusicDialog extends DialogFragment { + private final String YA_MUSIC_APP_NAME = "ru.yandex.music"; + private final String YA_RADIO_APPNAME = "ru.yandex.radio"; + private final String GOOGLE_PLAY_NAME = "market://details?id="; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) { + getDialog().setTitle(R.string.chooseApp); + View view = inflater.inflate(R.layout.start_music, null); + ButterKnife.findById(view,R.id.cancelButton).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getDialog().dismiss(); + } + }); + + View.OnClickListener onIconClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + String appName = ""; + switch (v.getId()) { + case R.id.yaMusic: + appName = YA_MUSIC_APP_NAME; + break; + case R.id.yaRadio: + appName = YA_RADIO_APPNAME; + } + Intent intent; + if (isAppInstalled(appName)) { + intent = getActivity().getPackageManager().getLaunchIntentForPackage(appName); + } else { + intent = new Intent(Intent.ACTION_VIEW, Uri.parse(GOOGLE_PLAY_NAME + appName)); + } + dismiss(); + startActivity(intent); + } + }; + ButterKnife.findById(view,R.id.yaRadio).setOnClickListener(onIconClickListener); + ButterKnife.findById(view,R.id.yaMusic).setOnClickListener(onIconClickListener); + return view; + } + + private boolean isAppInstalled(String appPkgName) { + boolean isAppInstalled = false; + try { + if (getActivity().getPackageManager().getPackageInfo(appPkgName, PackageManager.GET_META_DATA) != null) { + isAppInstalled = true; + } + ; + } catch (PackageManager.NameNotFoundException ex) { + ex.printStackTrace(); + } + return isAppInstalled; + } +} \ No newline at end of file diff --git a/Singers/app/src/main/java/ru/daria/singers/Singer.java b/Singers/app/src/main/java/ru/daria/singers/Singer.java index ca8efa6..3b63cf2 100644 --- a/Singers/app/src/main/java/ru/daria/singers/Singer.java +++ b/Singers/app/src/main/java/ru/daria/singers/Singer.java @@ -1,7 +1,6 @@ package ru.daria.singers; import java.io.Serializable; -import java.util.IllegalFormatException; import java.util.List; import java.util.Map; @@ -113,38 +112,4 @@ public String genresToString() { public String toString() { return name.toString(); } - - /** - * Функция возвращает окончание для множественного числа слова на основании числа и массива окончаний - * - * @param number int Число на основе которого нужно сформировать окончание - * @param endingArray Array Массив слов или окончаний для чисел (1, 4, 5), - * например array('песня', 'песни', 'песен') - * @return String - */ - public String getEnding(int number, String[] endingArray) { - if (endingArray.length != 3) - throw new ArrayIndexOutOfBoundsException("Out of bounds exception. Array must contains 3 elements!"); - number = number % 100; - String ending = ""; - if (number >= 11 && number <= 19) { - ending = endingArray[2]; - } else { - int i = number % 10; - switch (i) { - case (1): - ending = endingArray[0]; - break; - case (2): - case (3): - case (4): - ending = endingArray[1]; - break; - default: - ending = endingArray[2]; - } - } - return ending; - } - } diff --git a/Singers/app/src/main/res/drawable/ic_ya_music.png b/Singers/app/src/main/res/drawable/ic_ya_music.png new file mode 100644 index 0000000..e6423ec Binary files /dev/null and b/Singers/app/src/main/res/drawable/ic_ya_music.png differ diff --git a/Singers/app/src/main/res/drawable/ic_ya_radio.png b/Singers/app/src/main/res/drawable/ic_ya_radio.png new file mode 100644 index 0000000..9949133 Binary files /dev/null and b/Singers/app/src/main/res/drawable/ic_ya_radio.png differ diff --git a/Singers/app/src/main/res/layout/about_program.xml b/Singers/app/src/main/res/layout/about_program.xml new file mode 100644 index 0000000..8d9cdcc --- /dev/null +++ b/Singers/app/src/main/res/layout/about_program.xml @@ -0,0 +1,41 @@ + + + + + + + + + +