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 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Singers/app/src/main/res/layout/activity_main.xml b/Singers/app/src/main/res/layout/activity_main.xml
index 4d3a1e9..d62211d 100644
--- a/Singers/app/src/main/res/layout/activity_main.xml
+++ b/Singers/app/src/main/res/layout/activity_main.xml
@@ -16,6 +16,11 @@
layout="@layout/toolbar" />
-
+
+
diff --git a/Singers/app/src/main/res/layout/details.xml b/Singers/app/src/main/res/layout/details.xml
index 0875fdd..6c210f8 100644
--- a/Singers/app/src/main/res/layout/details.xml
+++ b/Singers/app/src/main/res/layout/details.xml
@@ -7,19 +7,10 @@
android:fitsSystemWindows="true"
tools:context="ru.daria.singers.MainActivity">
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Singers/app/src/main/res/menu/options_menu.xml b/Singers/app/src/main/res/menu/options_menu.xml
index 2161c87..9126593 100644
--- a/Singers/app/src/main/res/menu/options_menu.xml
+++ b/Singers/app/src/main/res/menu/options_menu.xml
@@ -2,15 +2,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="ru.daria.singers.MainActivity">
-
+
+ android:title="@string/search"/>
+
+
+
diff --git a/Singers/app/src/main/res/values/plurals.xml b/Singers/app/src/main/res/values/plurals.xml
new file mode 100644
index 0000000..1b58546
--- /dev/null
+++ b/Singers/app/src/main/res/values/plurals.xml
@@ -0,0 +1,19 @@
+
+
+
+ - нет песен
+ - %1$d песня
+ - %1$d песни
+ - %1$d песни
+ - %1$d песен
+ - %1$d песен
+
+
+ - нет альбомов
+ - %1$d альбом
+ - %1$d альбома
+ - %1$d альбома
+ - %1$d альбомов
+ - %1$d альбомов
+
+
\ No newline at end of file
diff --git a/Singers/app/src/main/res/values/strings.xml b/Singers/app/src/main/res/values/strings.xml
index 0ab3653..7a17cf4 100644
--- a/Singers/app/src/main/res/values/strings.xml
+++ b/Singers/app/src/main/res/values/strings.xml
@@ -1,7 +1,20 @@
- Исполнители
+ Исполнители
Введите имя исполнителя…
Настройки
#FFFFFF
- MusicArtists
+ MusicArtists
+ Поиск
+ О программе
+ Music Artists for Android
+
+ Программа создана в рамках проекта \"Мобилизация\" компании Яндекс \n
+ Версия: 0.0.1
+
+ Обратная связь
+ sukmanovadarya@yandex.ru
+ "Music Artists" problem
+ Напишите о вашей проблеме...
+
+ Выберите приложение
diff --git a/Singers/build.gradle b/Singers/build.gradle
index a4752eb..cf92d68 100644
--- a/Singers/build.gradle
+++ b/Singers/build.gradle
@@ -5,7 +5,8 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.5.0'
+ classpath 'com.android.tools.build:gradle:2.2.0-alpha5'
+ classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -19,4 +20,8 @@ allprojects {
task clean(type: Delete) {
delete rootProject.buildDir
+}
+
+configurations.all {
+ resolutionStrategy.force 'com.android.support:support-annotations:22.1.0'
}
\ No newline at end of file