Commit 6fd86c77 authored by Lucas Braz Cunha's avatar Lucas Braz Cunha

Issue AGILE#151: List Sectors received from back-end

Signed-off-by: Lucas Braz Cunha's avatarLucas B. Cunha <lbc16@inf.ufpr.br>
parent 6401bcea
......@@ -25,13 +25,14 @@ dependencies {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.google.code.gson:gson:2.7'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.android.support.test.espresso:espresso-core:2.2.2'
compile 'com.android.support.constraint:constraint-layout:1.0.1'
compile 'com.prolificinteractive:material-calendarview:1.4.3'
compile 'com.android.support:recyclerview-v7:25.3.1'
testCompile 'junit:junit:4.12'
}
......@@ -45,7 +45,7 @@ import java.util.List;
import br.ufpr.c3sl.agendador.agendador.helpers.ConnectionChecker;
import br.ufpr.c3sl.agendador.agendador.helpers.ConnectionErrorDialog;
import br.ufpr.c3sl.agendador.agendador.helpers.CustomAdapter;
import br.ufpr.c3sl.agendador.agendador.helpers.PhotoSelectionAdapter;
import br.ufpr.c3sl.agendador.agendador.helpers.DataValidador;
import br.ufpr.c3sl.agendador.agendador.helpers.Mask;
import br.ufpr.c3sl.agendador.agendador.helpers.ObscuredSharedPreferences;
......@@ -67,7 +67,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
et_city, et_state, et_complement, et_phone, et_phone2,
et_email, et_new_password, et_password_confirmation;
private ImageView imgv_profile;
private ImageView imv_profile;
private ProgressBar pb_account;
private RadioButton rb_no, rb_yes;
private Button btn_update, btn_cancel;
......@@ -163,7 +163,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
tv_email_warning = (TextView) findViewById(R.id.tv_account_email_warning);
tv_account_new_password_warning = (TextView) findViewById(R.id.tv_account_new_password_warning);
tv_password_confirm_warning = (TextView) findViewById(R.id.tv_account_confirm_password_warning);
imgv_profile = (ImageView) findViewById(R.id.img_account_photo);
imv_profile = (ImageView) findViewById(R.id.img_account_photo);
rb_no = (RadioButton) findViewById(R.id.rb_has_disability_no);
rb_yes = (RadioButton) findViewById(R.id.rb_has_disability_yes);
......@@ -193,7 +193,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
float percentage = 1.5f * ((float) Math.abs(verticalOffset) / appBarLayout.getTotalScrollRange());
imgv_profile.setAlpha(1 - percentage);
imv_profile.setAlpha(1 - percentage);
btn_photo.setAlpha(1 - percentage);
}
});
......@@ -313,7 +313,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
final String[] opts = {getString(R.string.prof_pic_update), getString(R.string.prof_pic_remove)};
int[] drawableIds = {android.R.drawable.ic_menu_camera, android.R.drawable.ic_menu_close_clear_cancel};
final CustomAdapter arrayAdapter = new CustomAdapter(getBaseContext(), opts, drawableIds);
final PhotoSelectionAdapter arrayAdapter = new PhotoSelectionAdapter(getBaseContext(), opts, drawableIds);
builderSingle.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
......@@ -329,7 +329,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
if(which == 1){
isPhotoDelete = true;
isChangingPhoto = true;
imgv_profile.setImageBitmap(null);
imv_profile.setImageBitmap(null);
}
else{
checkBuildVersion();
......@@ -342,7 +342,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
});
if(userPhotoHelper.existsPhoto()){
userPhotoHelper.updateImgView(imgv_profile, userPhotoHelper.getPhotoFileUri());
userPhotoHelper.updateImgView(imv_profile, userPhotoHelper.getPhotoFileUri());
}
isChangingPassword = false;
......@@ -384,9 +384,9 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
loadData();
scrollUp();
if(userPhotoHelper.existsPhoto())
userPhotoHelper.updateImgView(imgv_profile, userPhotoHelper.getPhotoFileUri());
userPhotoHelper.updateImgView(imv_profile, userPhotoHelper.getPhotoFileUri());
else
imgv_profile.setImageBitmap(null);
imv_profile.setImageBitmap(null);
} else {
Intent intent = new Intent(AccountActivity.this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
......@@ -424,9 +424,9 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
loadData();
scrollUp();
if(userPhotoHelper.existsPhoto())
userPhotoHelper.updateImgView(imgv_profile, userPhotoHelper.getPhotoFileUri());
userPhotoHelper.updateImgView(imv_profile, userPhotoHelper.getPhotoFileUri());
else
imgv_profile.setImageBitmap(null);
imv_profile.setImageBitmap(null);
} else {
Intent intent = new Intent(AccountActivity.this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
......@@ -529,9 +529,9 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
setButtonVisible(false);
loadData();
if(userPhotoHelper.existsPhoto())
userPhotoHelper.updateImgView(imgv_profile, userPhotoHelper.getPhotoFileUri());
userPhotoHelper.updateImgView(imv_profile, userPhotoHelper.getPhotoFileUri());
else
imgv_profile.setImageBitmap(null);
imv_profile.setImageBitmap(null);
}
private void loadData() {
......@@ -1018,7 +1018,7 @@ public class AccountActivity extends AppCompatActivity implements AccountView {
isPhotoDelete = false;
//TODO:same as above.
if(userPhotoHelper.updateImgView(imgv_profile, userPhotoHelper.getTempFileUri()))
if(userPhotoHelper.updateImgView(imv_profile, userPhotoHelper.getTempFileUri()))
{
//show message if update fails
}
......
package br.ufpr.c3sl.agendador.agendador;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import java.util.List;
import br.ufpr.c3sl.agendador.agendador.helpers.ConnectionErrorDialog;
import br.ufpr.c3sl.agendador.agendador.helpers.SectorArrayAdapter;
import br.ufpr.c3sl.agendador.agendador.models.SectorInput;
import br.ufpr.c3sl.agendador.agendador.presenters.TermPresenter;
import br.ufpr.c3sl.agendador.agendador.views.TermView;
......@@ -19,7 +29,13 @@ public class TermActivity extends AppCompatActivity implements TermView {
private List<SectorInput> sectors;
private ListView lv_sectors;
private RecyclerView rv_sectors;
private ProgressBar pb_term;
private ScrollView sv_term;
private ConnectionFailureDialog dg_connection_failure;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -53,7 +69,20 @@ public class TermActivity extends AppCompatActivity implements TermView {
}
});
lv_sectors = (ListView) findViewById(R.id.lv_term_sectors);
pb_term = (ProgressBar) findViewById(R.id.pb_termact);
sv_term = (ScrollView) findViewById(R.id.sv_termact);
sv_term.setVisibility(View.INVISIBLE);
rv_sectors = (RecyclerView) findViewById(R.id.rv_term_sectors);
RecyclerView.LayoutManager layout = new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false);
rv_sectors.setLayoutManager(layout);
termPresenter.bindView(this);
termPresenter.requestSectors();
}
......@@ -72,20 +101,64 @@ public class TermActivity extends AppCompatActivity implements TermView {
}
// TODO: 02/06/17 to implement!!!
//implement handler of listView
//after sectors request, dependents request receives 401 - unauthorized
// TODO: 02/06/17
//after sectors request, dependents request receives 401 - Não está acontecendo(?) Checar novamente
// TODO: 06/06/17 tratar casoss em que a requisição falhe!
@Override
public void showLayout(boolean enabled) {
rv_sectors.setAdapter(new SectorArrayAdapter(this, sectors));
sv_term.setVisibility(View.VISIBLE);
}
// TODO: 06/06/17 usar o set progressBar para deixar o layout escondido ou mudar?
@Override
public void setProgressBar(boolean enabled) {
if (enabled) {
pb_term.setVisibility(View.VISIBLE);
sv_term.setVisibility(View.INVISIBLE);
} else {
pb_term.setVisibility(View.INVISIBLE);
}
}
public void successfulSectors(List<SectorInput> sectors){
public void successfulSectors(List<SectorInput> sectors) {
this.sectors = sectors;
}
public void onRequestFailure(){
Bundle bundle = new Bundle();
if(dg_connection_failure == null){
dg_connection_failure = new ConnectionFailureDialog();
}
bundle.putString(ConnectionErrorDialog.DIALOG_MESSAGE_KEY, getString(R.string.dialog_term_error));
dg_connection_failure.setArguments(bundle);
dg_connection_failure.show(getFragmentManager(), ConnectionErrorDialog.DIALOG_CONNECTION_ERROR);
}
public static class ConnectionFailureDialog extends DialogFragment {
public static final String DIALOG_MESSAGE_KEY = "message";
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(getArguments().getString(DIALOG_MESSAGE_KEY))
.setTitle(getString(R.string.warningDialog_title))
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Activity activity = getActivity();
activity.onBackPressed();
}
});
return builder.create();
}
}
}
......@@ -13,16 +13,16 @@ import br.ufpr.c3sl.agendador.agendador.R;
/**
* Created by Lucas B. Cunha on 29/03/17.
*/
public class CustomAdapter extends BaseAdapter {
public class PhotoSelectionAdapter extends BaseAdapter {
private Context mContext;
private String[] title;
private int[] imgs_id;
private int[] imgsId;
public CustomAdapter(Context context, String[] text1,int[] imageIds) {
mContext = context;
title = text1;
imgs_id = imageIds;
public PhotoSelectionAdapter(Context context, String[] text1, int[] imageIds) {
this.mContext = context;
this.title = text1;
this.imgsId = imageIds;
}
......@@ -39,15 +39,21 @@ public class CustomAdapter extends BaseAdapter {
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row;
row = inflater.inflate(R.layout.custom_adapter_row, parent, false);
TextView title;
ImageView i1;
if( convertView == null) {
row = LayoutInflater.from(mContext)
.inflate(R.layout.custom_adapter_row, parent, false);
} else {
row = convertView;
}
i1 = (ImageView) row.findViewById(R.id.imgv_adapter);
title = (TextView) row.findViewById(R.id.tv_adapter);
title.setText(this.title[position]);
i1.setImageResource(imgs_id[position]);
i1.setImageResource(imgsId[position]);
return (row);
}
}
package br.ufpr.c3sl.agendador.agendador.helpers;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.List;
import br.ufpr.c3sl.agendador.agendador.R;
import br.ufpr.c3sl.agendador.agendador.models.SectorInput;
/**
* Created by Lucas B. Cunha on 02/06/17.
*/
public class SectorArrayAdapter {
public class SectorArrayAdapter extends RecyclerView.Adapter{
private List<SectorInput> sectors;
private Context context;
public SectorArrayAdapter(Context context, List<SectorInput> sectors){
super();
this.sectors = sectors;
this.context = context;
}
/**
* Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
* an item.
* <p>
* This new ViewHolder should be constructed with a new View that can represent the items
* of the given type. You can either create a new View manually or inflate it from an XML
* layout file.
* <p>
* The new ViewHolder will be used to display items of the adapter using
* {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display
* different items in the data set, it is a good idea to cache references to sub views of
* the View to avoid unnecessary {@link View#findViewById(int)} calls.
*
* @param parent The ViewGroup into which the new View will be added after it is bound to
* an adapter position.
* @param viewType The view type of the new View.
* @return A new ViewHolder that holds a View of the given view type.
* @see #getItemViewType(int)
* @see #onBindViewHolder(ViewHolder, int)
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context)
.inflate(R.layout.item_sector_list, parent, false);
return new SectorHolder(view);
}
/**
* Called by RecyclerView to display the data at the specified position. This method should
* update the contents of the {@link ViewHolder#itemView} to reflect the item at the given
* position.
* <p>
* Note that unlike {@link ListView}, RecyclerView will not call this method
* again if the position of the item changes in the data set unless the item itself is
* invalidated or the new position cannot be determined. For this reason, you should only
* use the <code>position</code> parameter while acquiring the related data item inside
* this method and should not keep a copy of it. If you need the position of an item later
* on (e.g. in a click listener), use {@link ViewHolder#getAdapterPosition()} which will
* have the updated adapter position.
* <p>
* Override {@link #onBindViewHolder(ViewHolder, int, List)} instead if Adapter can
* handle efficient partial bind.
*
* @param holder The ViewHolder which should be updated to represent the contents of the
* item at the given position in the data set.
* @param position The position of the item within the adapter's data set.
*/
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
SectorHolder sectorHolder = (SectorHolder) holder;
SectorInput sector = sectors.get(position);
sectorHolder.name.setText(sector.getmName());
String s = sector.getmAbsenceMax() + "";
sectorHolder.absences.setText(s);
}
/**
* Returns the total number of sectors in the data set held by the adapter.
*
* @return The total number of sectors in this adapter.
*/
@Override
public int getItemCount() {
return sectors.size();
}
}
package br.ufpr.c3sl.agendador.agendador.helpers;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import br.ufpr.c3sl.agendador.agendador.R;
/**
* Created by Lucas B. Cunha on 06/06/17.
*/
public class SectorHolder extends RecyclerView.ViewHolder{
final TextView name;
final TextView absences;
SectorHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.list_sector_name);
absences = (TextView) view.findViewById(R.id.list_absence_max);
}
}
......@@ -50,4 +50,8 @@ public class SectorInput {
return this.mName;
}
public int getmAbsenceMax(){return this.mAbsenceMax;}
}
......@@ -70,10 +70,6 @@ public class SchedulingPresenter extends BasePresenter<SchedulingView> {
List<UserOutput> dependents = response.body();
switch (status) {
/*case 404:
Log.d("Server response", "404 - Falha!");
//schedulingPresenter.view().setProgressBar(false);
break;*/
case 200:
Log.d("Server response", getClass().getName() + ": 200 - Sucesso!");
updateToken(headers);
......
......@@ -4,7 +4,6 @@ import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -12,7 +11,6 @@ import java.util.Map;
import br.ufpr.c3sl.agendador.agendador.TermActivity;
import br.ufpr.c3sl.agendador.agendador.helpers.ObscuredSharedPreferences;
import br.ufpr.c3sl.agendador.agendador.models.SectorInput;
import br.ufpr.c3sl.agendador.agendador.models.UserOutput;
import br.ufpr.c3sl.agendador.agendador.network.ApiEndpoints;
import br.ufpr.c3sl.agendador.agendador.network.ApiUtils;
import okhttp3.Headers;
......@@ -61,7 +59,6 @@ public class TermPresenter extends BasePresenter<TermActivity>{
final ApiEndpoints service = ApiUtils.request(header);
Call<List<SectorInput>> listCall = service.requestSectors();
termPresenter.view().showLayout(false);
termPresenter.view().setProgressBar(true);
listCall.enqueue(new Callback<List<SectorInput>>() {
......@@ -70,16 +67,19 @@ public class TermPresenter extends BasePresenter<TermActivity>{
Headers headers = response.headers();
int status = response.code();
List<SectorInput> sectors = response.body();
switch (status) {
case 200:
Log.d("Server response", getClass().getName() + ": 200 - Sucesso!");
updateToken(headers);
//has to be done before showing layout
termPresenter.view().successfulSectors(sectors);
termPresenter.view().showLayout(true);
termPresenter.view().setProgressBar(false);
termPresenter.view().successfulSectors(sectors);
break;
default:
Log.d("Server response", getClass().getName() + ": ERRO:" + status);
termPresenter.view().onRequestFailure();
break;
}
......@@ -87,11 +87,9 @@ public class TermPresenter extends BasePresenter<TermActivity>{
@Override
public void onFailure(Call<List<SectorInput>> call, Throwable t) {
// TODO: 02/06/17 Warn user about connection failure
Log.d("Server response", getClass().getName() + ": Requisição falhou!!");
Toast.makeText(context,"Ocorreu um problema ao carregar essa página.", Toast.LENGTH_SHORT).show();
//schedulingPresenter.view().setNoConnection(true);
//termPresenter.view().setProgressBar(false);
termPresenter.view().setProgressBar(false);
termPresenter.view().onRequestFailure();
}
});
......
......@@ -10,4 +10,6 @@ public interface TermView {
void showLayout(boolean enabled);
void setProgressBar(boolean enabled);
void onRequestFailure();
}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/sv_termact"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="false">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
......@@ -50,30 +56,14 @@
android:textAlignment="center"
android:textSize="16sp"/>
<ListView
android:id="@+id/lv_term_sectors"
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_term_sectors"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="- Setor Ambiental: 2 faltas."
android:textStyle="bold"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:textSize="16sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="- Setor Ambiental: 2 faltas."
android:textStyle="bold"
android:layout_gravity="center_horizontal"
android:textAlignment="center"
android:textSize="16sp"
/>
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:background="#cfd0d1"/>
<Button
android:id="@+id/btn_term_refusal"
android:layout_width="wrap_content"
......@@ -97,4 +87,15 @@
android:text="@string/accept_continue"/>
</LinearLayout>
</ScrollView>
\ No newline at end of file
</ScrollView>
<ProgressBar
android:id="@+id/pb_termact"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:indeterminate="true"
android:visibility="invisible" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/list_sector_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="@color/colorBlack" />
<LinearLayout
android:id="@+id/list_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="@color/colorBlack"
android:text="@string/list_item_absences"/>
<TextView
android:id="@+id/list_absence_max"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorBlack"
android:textSize="12sp"/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
......@@ -147,4 +147,8 @@
<string name="scheduling_date">Datas disponíveis</string>
<string name="highlight_date_accessibility">Círculo ao redor de uma data demonstra que ela está disponível para agendamento</string>
<string name="scheduling_dependent_hint">Selecione um cidadão</string>
<string name="list_item_absences">Limite de faltas: </string>
<string name="dialog_term_error">Ocorreu um erro ao carregar, por favor:
* Verifique sua conexão com a internet;
* tente novamente mais tarde.</string>
</resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment