mirror of
https://github.com/freeedcom/ai-codereviewer.git
synced 2025-06-30 21:04:16 +00:00
add project adins
This commit is contained in:
parent
ad06ac5505
commit
f8f85d679d
5299 changed files with 625430 additions and 0 deletions
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="spb_default_color">#33b5e5</color>
|
||||
<dimen name="spb_default_stroke_separator_length">4dp</dimen>
|
||||
<dimen name="spb_default_stroke_width">4dp</dimen>
|
||||
<integer name="spb_default_sections_count">4</integer>
|
||||
<integer name="spb_default_interpolator">0</integer>
|
||||
<item name="spb_default_speed" format="float" type="string">1.0</item>
|
||||
<bool name="spb_default_reversed">false</bool>
|
||||
<bool name="spb_default_mirror_mode">false</bool>
|
||||
<bool name="spb_default_progressiveStart_activated">false</bool>
|
||||
</resources>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval" >
|
||||
<solid android:color="@color/gradient_end" />
|
||||
</shape>
|
|
@ -0,0 +1,34 @@
|
|||
package com.adins.mss.foundation.dialog.gitonway.lib.effects;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.adins.libs.nineoldandroids.animation.ObjectAnimator;
|
||||
|
||||
/*
|
||||
* Copyright 2014 litao
|
||||
* https://github.com/sd6352051/NiftyDialogEffects
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
public class Fall extends BaseEffects {
|
||||
|
||||
@Override
|
||||
protected void setupAnimation(View view) {
|
||||
getAnimatorSet().playTogether(
|
||||
ObjectAnimator.ofFloat(view, "scaleX", 2, 1.5f, 1).setDuration(mDuration),
|
||||
ObjectAnimator.ofFloat(view, "scaleY", 2, 1.5f, 1).setDuration(mDuration),
|
||||
ObjectAnimator.ofFloat(view, "alpha", 0, 1).setDuration(mDuration * 3 / 2)
|
||||
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package com.adins.mss.foundation.services;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.adins.mss.base.GlobalData;
|
||||
import com.adins.mss.foundation.camerainapp.helper.Logger;
|
||||
import com.services.ForegroundServiceNotification;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author glen.iglesias
|
||||
* A Service to hold several Threads which supposed to work on background. Such Thread is actually a subclass of Thread,
|
||||
* named ScheduledItem. This class is tightly coupled to GlobalData, so application could access this object via GlobalData
|
||||
* <p>
|
||||
* Remember to make sure Service is started before accessing from GlobalData, as GlobalData is set when the most recent Service
|
||||
* started
|
||||
*/
|
||||
public class AutoSendSerivce extends Service {
|
||||
|
||||
private List<ScheduledItem> scheduledItems;
|
||||
|
||||
public AutoSendSerivce() {
|
||||
}
|
||||
|
||||
//=== Method ===//
|
||||
|
||||
/**
|
||||
* Add ScheduledItem into AutoSendService, and start the ScheduledItem. If an ScheduledItem with same scheduleId
|
||||
* already existed, the new ScheduledItem will be rejected
|
||||
*
|
||||
* @param item ScheduledItem to be added into list
|
||||
*/
|
||||
public void addScheduledItem(ScheduledItem item) {
|
||||
if (scheduledItems == null) {
|
||||
scheduledItems = new ArrayList<ScheduledItem>();
|
||||
}
|
||||
|
||||
//Check for double id
|
||||
ScheduledItem compare = getScheduleItemByName(item.getScheduleId());
|
||||
if (compare != null && compare.getScheduleId().equals(item.getScheduleId())) {
|
||||
Logger.e("AutoSendService", "ScheduledItem with same id exist");
|
||||
return;
|
||||
}
|
||||
|
||||
scheduledItems.add(item);
|
||||
item.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Logger.d("AutoSendServce", "onCreateCalled");
|
||||
//Tightly coupling self with GlobalData
|
||||
GlobalData.getSharedGlobalData().setAutoSendThread(this);
|
||||
|
||||
startForeground(ForegroundServiceNotification.getNotificationId(),
|
||||
ForegroundServiceNotification.getNotification(this));
|
||||
|
||||
// for (ScheduledItem schdItem : scheduledItems){
|
||||
// schdItem.start();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scheduleId ScheduledItem id of which to be retrieved
|
||||
* @return ScheduledItem with scheduleId, or null if no scheduleId match
|
||||
*/
|
||||
public ScheduledItem getScheduleItemByName(String scheduleId) {
|
||||
for (ScheduledItem item : scheduledItems) {
|
||||
if (scheduleId.equals(item.getScheduleId())) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume a paused ScheduledItem by scheduleId. If the interval has passed before it's resumed,
|
||||
* it will immediately trigger scheduled event.
|
||||
*
|
||||
* @param scheduleId scheduleId of ScheduledItem which to be resumed after being paused
|
||||
*/
|
||||
public void resumeScheduledItem(String scheduleId) {
|
||||
ScheduledItem schedItem = getScheduleItemByName(scheduleId);
|
||||
schedItem.resumeSchedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause a ScheduledItem by scheduleId. The interval counter still continue but won't trigger any event
|
||||
* if it's paused, and will be triggered on resume
|
||||
*
|
||||
* @param scheduleId scheduleId of ScheduledItem which to be paused
|
||||
*/
|
||||
public void pauseScheduledItem(String scheduleId) {
|
||||
ScheduledItem schedItem = getScheduleItemByName(scheduleId);
|
||||
schedItem.pauseSchedule();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,325 @@
|
|||
package com.adins.mss.base.dynamicform.form.questions.viewholder;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.adins.mss.base.GlobalData;
|
||||
import com.adins.mss.base.R;
|
||||
import com.adins.mss.base.crashlytics.FireCrash;
|
||||
import com.adins.mss.base.dynamicform.Constant;
|
||||
import com.adins.mss.base.dynamicform.DynamicFormActivity;
|
||||
import com.adins.mss.base.dynamicform.form.models.JsonDataRecommendationRequest;
|
||||
import com.adins.mss.base.dynamicform.form.models.JsonDataRecommendationResponse;
|
||||
import com.adins.mss.base.dynamicform.form.models.JsonDataSpRequest;
|
||||
import com.adins.mss.base.dynamicform.form.models.JsonDataSpResponse;
|
||||
import com.adins.mss.base.util.GsonHelper;
|
||||
import com.adins.mss.constant.Global;
|
||||
import com.adins.mss.foundation.dialog.NiftyDialogBuilder;
|
||||
import com.adins.mss.foundation.http.HttpConnectionResult;
|
||||
import com.adins.mss.foundation.http.HttpCryptedConnection;
|
||||
import com.adins.mss.foundation.questiongenerator.QuestionBean;
|
||||
import com.adins.mss.foundation.questiongenerator.form.QuestionView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ButtonTextUrlViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final FragmentActivity mActivity;
|
||||
private final QuestionView mView;
|
||||
private final TextView mQuestionLabel;
|
||||
private final EditText mQuestionAnswer;
|
||||
private Button btnView;
|
||||
private QuestionBean mBean;
|
||||
|
||||
public ButtonTextUrlViewHolder(View itemView, FragmentActivity activity) {
|
||||
super(itemView);
|
||||
mActivity = activity;
|
||||
mView = (QuestionView) itemView.findViewById(R.id.question_text_button_url_layout);
|
||||
mQuestionLabel = (TextView) itemView.findViewById(R.id.question_text_button_url_label);
|
||||
mQuestionAnswer = (EditText) itemView.findViewById(R.id.et_url);
|
||||
btnView = (Button) itemView.findViewById(R.id.btn_view);
|
||||
}
|
||||
|
||||
public void bind(QuestionBean item, int number) {
|
||||
mBean = item;
|
||||
String qLabel = number + ". " + mBean.getQuestion_label();
|
||||
mQuestionLabel.setText(qLabel);
|
||||
mQuestionAnswer.setVisibility(View.GONE);
|
||||
|
||||
final String tag = mBean.getTag();
|
||||
if(Global.TAG_RECOMMMENDATION_QUESTION.equals(tag)){
|
||||
btnView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
String choiceFilter = mBean.getChoice_filter();
|
||||
choiceFilter = choiceFilter.replaceAll("\\{", "");
|
||||
choiceFilter = choiceFilter.replaceAll("\\}", "");
|
||||
Map<String, String> data = new HashMap<>();
|
||||
if (choiceFilter != null && !"".equalsIgnoreCase(choiceFilter)) {
|
||||
String[] identifierFilters = choiceFilter.split(",");
|
||||
for (int i = 0; i < identifierFilters.length; i++) {
|
||||
String identifier = identifierFilters[i];
|
||||
QuestionBean qBean = Constant.getListOfQuestion().get(identifier);
|
||||
if (qBean != null) {
|
||||
String answerBean = QuestionBean.getAnswer(qBean);
|
||||
if (answerBean == null) {
|
||||
answerBean = "";
|
||||
}
|
||||
data.put(identifier, answerBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetDataRecommendationAnswer getDataRecommendationAnswer = new GetDataRecommendationAnswer(data, tag);
|
||||
getDataRecommendationAnswer.execute();
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(Global.TAG_SP_QUESTION.equals(tag)){
|
||||
btnView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
String choiceFilter = mBean.getChoice_filter();
|
||||
choiceFilter = choiceFilter.replaceAll("\\{", "");
|
||||
choiceFilter = choiceFilter.replaceAll("\\}", "");
|
||||
Map<String, String> data = new HashMap<>();
|
||||
if (choiceFilter != null && !"".equalsIgnoreCase(choiceFilter)) {
|
||||
String[] identifierFilters = choiceFilter.split(",");
|
||||
for (int i = 0; i < identifierFilters.length; i++) {
|
||||
String identifier = identifierFilters[i];
|
||||
QuestionBean qBean = Constant.getListOfQuestion().get(identifier);
|
||||
if (qBean != null) {
|
||||
String answerBean = QuestionBean.getAnswer(qBean);
|
||||
if (answerBean == null) {
|
||||
answerBean = "";
|
||||
}
|
||||
data.put(identifier, answerBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetDataSpAnswer getDataSpAnswer = new GetDataSpAnswer(data, tag);
|
||||
getDataSpAnswer.execute();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
private class GetDataSpAnswer extends AsyncTask<Void, Void, JsonDataSpResponse>{
|
||||
private ProgressDialog progressDialog;
|
||||
private Map<String, String> dataCustomer;
|
||||
private String questionTag;
|
||||
|
||||
public GetDataSpAnswer(Map<String, String> dataCustomer, String questionTag) {
|
||||
this.dataCustomer = dataCustomer;
|
||||
this.questionTag = questionTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
progressDialog = ProgressDialog.show(mActivity, "", mActivity.getString(R.string.please_wait), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonDataSpResponse doInBackground(Void... voids) {
|
||||
JsonDataSpResponse response = new JsonDataSpResponse();
|
||||
JsonDataSpRequest request = new JsonDataSpRequest();
|
||||
String uuidTaskH = DynamicFormActivity.getHeader().getUuid_task_h();
|
||||
request.setUuidTaskH(uuidTaskH);
|
||||
request.setAudit(GlobalData.getSharedGlobalData().getAuditData());
|
||||
request.setQuestionTag(questionTag);
|
||||
request.setQuestionList(dataCustomer);
|
||||
|
||||
|
||||
String url = GlobalData.getSharedGlobalData().getURL_GET_DATA_QUESTION_BUTTON_TEXT();
|
||||
String json = GsonHelper.toJson(request);
|
||||
boolean encrypt = GlobalData.getSharedGlobalData().isEncrypt();
|
||||
boolean decrypt = GlobalData.getSharedGlobalData().isDecrypt();
|
||||
HttpCryptedConnection httpConn = new HttpCryptedConnection(mActivity, encrypt, decrypt);
|
||||
HttpConnectionResult serverResult;
|
||||
try {
|
||||
serverResult = httpConn.requestToServer(url, json, Global.DEFAULTCONNECTIONTIMEOUT);
|
||||
if(serverResult.isOK()){
|
||||
String result =serverResult.getResult();
|
||||
response =GsonHelper.fromJson(result, JsonDataSpResponse.class);
|
||||
}
|
||||
}catch (Exception e){
|
||||
FireCrash.log(e);
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
}catch (Exception ex){
|
||||
FireCrash.log(e);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(JsonDataSpResponse result) {
|
||||
if(progressDialog.isShowing()){
|
||||
try{
|
||||
progressDialog.dismiss();
|
||||
}catch (Exception e){
|
||||
FireCrash.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (null != result) {
|
||||
if (result.getStatus().getCode() == 0 &&
|
||||
"Success".equalsIgnoreCase(result.getStatus().getMessage())) {
|
||||
if (null != result.getResult()) {
|
||||
mQuestionAnswer.setText(result.getResult());
|
||||
setUrlText(result.getResult());
|
||||
} else {
|
||||
mBean.setAnswer("-");
|
||||
mQuestionAnswer.setText("-");
|
||||
}
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
String message = result.getStatus().getMessage();
|
||||
NiftyDialogBuilder dialogBuilder = NiftyDialogBuilder.getInstance(mActivity);
|
||||
dialogBuilder.withTitle(mActivity.getString(R.string.info_capital))
|
||||
.withMessage(message)
|
||||
.show();
|
||||
}
|
||||
} else {
|
||||
mBean.setAnswer("-");
|
||||
mQuestionAnswer.setText("-");
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class GetDataRecommendationAnswer extends AsyncTask<Void, Void, JsonDataRecommendationResponse>{
|
||||
private ProgressDialog progressDialog;
|
||||
private Map<String, String> dataCustomer;
|
||||
private String questionTag;
|
||||
|
||||
public GetDataRecommendationAnswer(Map<String, String> dataCustomer, String questionTag) {
|
||||
this.dataCustomer = dataCustomer;
|
||||
this.questionTag = questionTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
progressDialog = ProgressDialog.show(mActivity, "", mActivity.getString(R.string.please_wait), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonDataRecommendationResponse doInBackground(Void... voids) {
|
||||
JsonDataRecommendationResponse response = new JsonDataRecommendationResponse();
|
||||
JsonDataRecommendationRequest request = new JsonDataRecommendationRequest();
|
||||
String uuidTaskH = DynamicFormActivity.getHeader().getUuid_task_h();
|
||||
request.setAudit(GlobalData.getSharedGlobalData().getAuditData());
|
||||
request.setQuestionTag(questionTag);
|
||||
request.setQuestionList(dataCustomer);
|
||||
request.setUuidTaskH(uuidTaskH);
|
||||
|
||||
String url = GlobalData.getSharedGlobalData().getURL_GET_DATA_QUESTION_BUTTON_TEXT();
|
||||
String json = GsonHelper.toJson(request);
|
||||
boolean encrypt = GlobalData.getSharedGlobalData().isEncrypt();
|
||||
boolean decrypt = GlobalData.getSharedGlobalData().isDecrypt();
|
||||
HttpCryptedConnection httpConn = new HttpCryptedConnection(mActivity, encrypt, decrypt);
|
||||
HttpConnectionResult serverResult;
|
||||
try {
|
||||
serverResult = httpConn.requestToServer(url, json, Global.DEFAULTCONNECTIONTIMEOUT);
|
||||
if(serverResult.isOK()){
|
||||
String result = serverResult.getResult();
|
||||
response =GsonHelper.fromJson(result, JsonDataRecommendationResponse.class);
|
||||
}
|
||||
}catch (Exception e){
|
||||
FireCrash.log(e);
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
}catch (Exception ex){
|
||||
FireCrash.log(e);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(JsonDataRecommendationResponse response) {
|
||||
if(progressDialog.isShowing()){
|
||||
try{
|
||||
progressDialog.dismiss();
|
||||
}catch (Exception e){
|
||||
FireCrash.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (null != response) {
|
||||
if (response.getStatus().getCode() == 0 &&
|
||||
"Success".equalsIgnoreCase(response.getStatus().getMessage())) {
|
||||
if (null != response.getResult()) {
|
||||
mBean.setAnswer(response.getResult());
|
||||
mQuestionAnswer.setText(response.getResult());
|
||||
} else {
|
||||
mBean.setAnswer("-");
|
||||
mQuestionAnswer.setText("-");
|
||||
}
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mBean.setAnswer(null);
|
||||
|
||||
String message = response.getStatus().getMessage();
|
||||
NiftyDialogBuilder dialogBuilder = NiftyDialogBuilder.getInstance(mActivity);
|
||||
dialogBuilder.withTitle(mActivity.getString(R.string.info_capital))
|
||||
.withMessage(message)
|
||||
.show();
|
||||
}
|
||||
} else {
|
||||
mBean.setAnswer("-");
|
||||
mQuestionAnswer.setText("-");
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void setUrlText(final String url) {
|
||||
SpannableString spannableString = new SpannableString(url);
|
||||
|
||||
// Set the color to blue
|
||||
ForegroundColorSpan blueColor = new ForegroundColorSpan(ContextCompat.getColor(mActivity, R.color.blueUrl));
|
||||
spannableString.setSpan(blueColor, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
// Underline the text
|
||||
UnderlineSpan underlineSpan = new UnderlineSpan();
|
||||
spannableString.setSpan(underlineSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
// Make the text clickable
|
||||
ClickableSpan clickableSpan = new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
mActivity.startActivity(browserIntent);
|
||||
}
|
||||
};
|
||||
spannableString.setSpan(clickableSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
mBean.setAnswer(spannableString.toString());
|
||||
mQuestionAnswer.setText(spannableString);
|
||||
mQuestionAnswer.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
mQuestionAnswer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.adins.mss.base.dynamicform.form;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearSmoothScroller;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by gigin.ginanjar on 31/08/2016.
|
||||
*/
|
||||
public class ScrollingLinearLayoutManager extends LinearLayoutManager {
|
||||
private final int duration;
|
||||
private boolean isScrollEnable = true;
|
||||
|
||||
public ScrollingLinearLayoutManager(Context context, int orientation, boolean reverseLayout, int duration) {
|
||||
super(context, orientation, reverseLayout);
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean supportsPredictiveItemAnimations() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public void setScrollEnable(boolean flag) {
|
||||
this.isScrollEnable = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canScrollVertically() {
|
||||
return isScrollEnable && super.canScrollVertically();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
|
||||
int position) {
|
||||
View firstVisibleChild = recyclerView.getChildAt(0);
|
||||
int itemHeight = firstVisibleChild.getHeight();
|
||||
int currentPosition = recyclerView.getChildAdapterPosition(firstVisibleChild);
|
||||
int distanceInPixels = Math.abs((currentPosition - position) * itemHeight);
|
||||
if (distanceInPixels == 0) {
|
||||
distanceInPixels = (int) Math.abs(firstVisibleChild.getY());
|
||||
}
|
||||
SmoothScroller smoothScroller = new SmoothScroller(recyclerView.getContext(), distanceInPixels, duration);
|
||||
smoothScroller.setTargetPosition(position);
|
||||
startSmoothScroll(smoothScroller);
|
||||
}
|
||||
|
||||
private class SmoothScroller extends LinearSmoothScroller {
|
||||
private static final int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000;
|
||||
private final float distanceInPixels;
|
||||
private final float duration;
|
||||
|
||||
public SmoothScroller(Context context, int distanceInPixels, int duration) {
|
||||
super(context);
|
||||
this.distanceInPixels = distanceInPixels;
|
||||
float millisPerPx = calculateSpeedPerPixel(context.getResources().getDisplayMetrics());
|
||||
this.duration = distanceInPixels < TARGET_SEEK_SCROLL_DISTANCE_PX ? (int) (Math.abs(distanceInPixels) * millisPerPx) : duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointF computeScrollVectorForPosition(int targetPosition) {
|
||||
return ScrollingLinearLayoutManager.this.computeScrollVectorForPosition(targetPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateTimeForScrolling(int dx) {
|
||||
float proportion = (float) dx / distanceInPixels;
|
||||
return (int) (duration * proportion);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,663 @@
|
|||
/*
|
||||
* Copyright 2013 Chris Banes
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package uk.co.senab.actionbarpulltorefresh.library;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.adins.mss.foundation.camerainapp.helper.Logger;
|
||||
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import uk.co.senab.actionbarpulltorefresh.library.listeners.HeaderViewListener;
|
||||
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;
|
||||
import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.ViewDelegate;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
public class PullToRefreshAttacher {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String LOG_TAG = "PullToRefreshAttacher";
|
||||
|
||||
/* Member Variables */
|
||||
private final int mTouchSlop;
|
||||
private final float mRefreshScrollDistance;
|
||||
private final WeakHashMap<View, ViewDelegate> mRefreshableViews;
|
||||
private final boolean mRefreshOnUp;
|
||||
private final int mRefreshMinimizeDelay;
|
||||
private final boolean mRefreshMinimize;
|
||||
private final int[] mViewLocationResult = new int[2];
|
||||
private final Rect mRect = new Rect();
|
||||
private final AddHeaderViewRunnable mAddHeaderViewRunnable;
|
||||
private EnvironmentDelegate mEnvironmentDelegate;
|
||||
private HeaderTransformer mHeaderTransformer;
|
||||
private OnRefreshListener mOnRefreshListener;
|
||||
private Activity mActivity;
|
||||
private View mHeaderView;
|
||||
private HeaderViewListener mHeaderViewListener;
|
||||
private float mInitialMotionY, mLastMotionY, mPullBeginY;
|
||||
private float mInitialMotionX;
|
||||
private boolean mIsBeingDragged, mIsRefreshing, mHandlingTouchEventFromDown;
|
||||
private View mViewBeingDragged;
|
||||
private boolean mIsDestroyed = false;
|
||||
private final Runnable mRefreshMinimizeRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
minimizeHeader();
|
||||
}
|
||||
};
|
||||
|
||||
protected PullToRefreshAttacher(Activity activity, Options options) {
|
||||
if (activity == null) {
|
||||
throw new IllegalArgumentException("activity cannot be null");
|
||||
}
|
||||
if (options == null) {
|
||||
Log.i(LOG_TAG, "Given null options so using default options.");
|
||||
options = new Options();
|
||||
}
|
||||
|
||||
mActivity = activity;
|
||||
mRefreshableViews = new WeakHashMap<View, ViewDelegate>();
|
||||
|
||||
// Copy necessary values from options
|
||||
mRefreshScrollDistance = options.refreshScrollDistance;
|
||||
mRefreshOnUp = options.refreshOnUp;
|
||||
mRefreshMinimizeDelay = options.refreshMinimizeDelay;
|
||||
mRefreshMinimize = options.refreshMinimize;
|
||||
|
||||
// EnvironmentDelegate
|
||||
mEnvironmentDelegate = options.environmentDelegate != null
|
||||
? options.environmentDelegate
|
||||
: createDefaultEnvironmentDelegate();
|
||||
|
||||
// Header Transformer
|
||||
mHeaderTransformer = options.headerTransformer != null
|
||||
? options.headerTransformer
|
||||
: createDefaultHeaderTransformer();
|
||||
|
||||
// Get touch slop for use later
|
||||
mTouchSlop = ViewConfiguration.get(activity).getScaledTouchSlop();
|
||||
|
||||
// Get Window Decor View
|
||||
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
||||
|
||||
// Create Header view and then add to Decor View
|
||||
mHeaderView = LayoutInflater.from(
|
||||
mEnvironmentDelegate.getContextForInflater(activity)).inflate(
|
||||
options.headerLayout, decorView, false);
|
||||
if (mHeaderView == null) {
|
||||
throw new IllegalArgumentException("Must supply valid layout id for header.");
|
||||
}
|
||||
// Make Header View invisible so it still gets a layout pass
|
||||
mHeaderView.setVisibility(View.INVISIBLE);
|
||||
|
||||
// Notify transformer
|
||||
mHeaderTransformer.onViewCreated(activity, mHeaderView);
|
||||
|
||||
// Now HeaderView to Activity
|
||||
mAddHeaderViewRunnable = new AddHeaderViewRunnable();
|
||||
mAddHeaderViewRunnable.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a view which will be used to initiate refresh requests.
|
||||
*
|
||||
* @param view View which will be used to initiate refresh requests.
|
||||
*/
|
||||
void addRefreshableView(View view, ViewDelegate viewDelegate) {
|
||||
if (isDestroyed()) return;
|
||||
|
||||
// Check to see if view is null
|
||||
if (view == null) {
|
||||
Log.i(LOG_TAG, "Refreshable View is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
// ViewDelegate
|
||||
if (viewDelegate == null) {
|
||||
viewDelegate = InstanceCreationUtils.getBuiltInViewDelegate(view);
|
||||
}
|
||||
|
||||
// View to detect refreshes for
|
||||
mRefreshableViews.put(view, viewDelegate);
|
||||
}
|
||||
|
||||
void useViewDelegate(Class<?> viewClass, ViewDelegate delegate) {
|
||||
for (View view : mRefreshableViews.keySet()) {
|
||||
if (viewClass.isInstance(view)) {
|
||||
mRefreshableViews.put(view, delegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all views which were previously used to initiate refresh requests.
|
||||
*/
|
||||
void clearRefreshableViews() {
|
||||
mRefreshableViews.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called by your Activity's or Fragment's
|
||||
* onConfigurationChanged method.
|
||||
*
|
||||
* @param newConfig The new configuration
|
||||
*/
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
mHeaderTransformer.onConfigurationChanged(mActivity, newConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this Attacher is currently in a refreshing state.
|
||||
*/
|
||||
final boolean isRefreshing() {
|
||||
return mIsRefreshing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually set this Attacher's refreshing state. The header will be
|
||||
* displayed or hidden as requested.
|
||||
*
|
||||
* @param refreshing - Whether the attacher should be in a refreshing state,
|
||||
*/
|
||||
final void setRefreshing(boolean refreshing) {
|
||||
setRefreshingInt(null, refreshing, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when your refresh is complete and this view should reset itself
|
||||
* (header view will be hidden).
|
||||
* <p>
|
||||
* This is the equivalent of calling <code>setRefreshing(false)</code>.
|
||||
*/
|
||||
final void setRefreshComplete() {
|
||||
setRefreshingInt(null, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Listener to be called when a refresh is initiated.
|
||||
*/
|
||||
void setOnRefreshListener(OnRefreshListener listener) {
|
||||
mOnRefreshListener = listener;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
if (mIsDestroyed) return; // We've already been destroyed
|
||||
|
||||
// Remove the Header View from the Activity
|
||||
removeHeaderViewFromActivity(mHeaderView);
|
||||
|
||||
// Lets clear out all of our internal state
|
||||
clearRefreshableViews();
|
||||
|
||||
mActivity = null;
|
||||
mHeaderView = null;
|
||||
mHeaderViewListener = null;
|
||||
mEnvironmentDelegate = null;
|
||||
mHeaderTransformer = null;
|
||||
|
||||
mIsDestroyed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a {@link HeaderViewListener} which is called when the visibility
|
||||
* state of the Header View has changed.
|
||||
*/
|
||||
final void setHeaderViewListener(HeaderViewListener listener) {
|
||||
mHeaderViewListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Header View which is displayed when the user is pulling, or
|
||||
* we are refreshing.
|
||||
*/
|
||||
final View getHeaderView() {
|
||||
return mHeaderView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The HeaderTransformer currently used by this Attacher.
|
||||
*/
|
||||
HeaderTransformer getHeaderTransformer() {
|
||||
return mHeaderTransformer;
|
||||
}
|
||||
|
||||
final boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (DEBUG) {
|
||||
Logger.d(LOG_TAG, "onInterceptTouchEvent: " + event.toString());
|
||||
}
|
||||
|
||||
// If we're not enabled or currently refreshing don't handle any touch
|
||||
// events
|
||||
if (isRefreshing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final float x = event.getX(), y = event.getY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
// We're not currently being dragged so check to see if the user has
|
||||
// scrolled enough
|
||||
if (!mIsBeingDragged && mInitialMotionY > 0f) {
|
||||
final float yDiff = y - mInitialMotionY;
|
||||
final float xDiff = x - mInitialMotionX;
|
||||
|
||||
if (Math.abs(yDiff) > Math.abs(xDiff) && yDiff > mTouchSlop) {
|
||||
mIsBeingDragged = true;
|
||||
onPullStarted(y);
|
||||
} else if (yDiff < -mTouchSlop) {
|
||||
resetTouch();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
// If we're already refreshing, ignore
|
||||
if (canRefresh(true)) {
|
||||
for (View view : mRefreshableViews.keySet()) {
|
||||
if (isViewBeingDragged(view, event)) {
|
||||
mInitialMotionX = x;
|
||||
mInitialMotionY = y;
|
||||
mViewBeingDragged = view;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP: {
|
||||
resetTouch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) Logger.d(LOG_TAG, "onInterceptTouchEvent. Returning " + mIsBeingDragged);
|
||||
|
||||
return mIsBeingDragged;
|
||||
}
|
||||
|
||||
final boolean isViewBeingDragged(View view, MotionEvent event) {
|
||||
if (view.isShown() && mRefreshableViews.containsKey(view)) {
|
||||
// First we need to set the rect to the view's screen co-ordinates
|
||||
view.getLocationOnScreen(mViewLocationResult);
|
||||
final int viewLeft = mViewLocationResult[0], viewTop = mViewLocationResult[1];
|
||||
mRect.set(viewLeft, viewTop, viewLeft + view.getWidth(), viewTop + view.getHeight());
|
||||
|
||||
if (DEBUG) Logger.d(LOG_TAG, "isViewBeingDragged. View Rect: " + mRect.toString());
|
||||
|
||||
final int rawX = (int) event.getRawX(), rawY = (int) event.getRawY();
|
||||
if (mRect.contains(rawX, rawY)) {
|
||||
// The Touch Event is within the View's display Rect
|
||||
ViewDelegate delegate = mRefreshableViews.get(view);
|
||||
if (delegate != null) {
|
||||
// Now call the delegate, converting the X/Y into the View's co-ordinate system
|
||||
return delegate.isReadyForPull(view, rawX - mRect.left, rawY - mRect.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean onTouchEvent(MotionEvent event) {
|
||||
if (DEBUG) {
|
||||
Logger.d(LOG_TAG, "onTouchEvent: " + event.toString());
|
||||
}
|
||||
|
||||
// Record whether our handling is started from ACTION_DOWN
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
mHandlingTouchEventFromDown = true;
|
||||
}
|
||||
|
||||
// If we're being called from ACTION_DOWN then we must call through to
|
||||
// onInterceptTouchEvent until it sets mIsBeingDragged
|
||||
if (mHandlingTouchEventFromDown && !mIsBeingDragged) {
|
||||
onInterceptTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mViewBeingDragged == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
// If we're already refreshing ignore it
|
||||
if (isRefreshing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final float y = event.getY();
|
||||
|
||||
if (mIsBeingDragged && y != mLastMotionY) {
|
||||
final float yDx = y - mLastMotionY;
|
||||
|
||||
/**
|
||||
* Check to see if the user is scrolling the right direction
|
||||
* (down). We allow a small scroll up which is the check against
|
||||
* negative touch slop.
|
||||
*/
|
||||
if (yDx >= -mTouchSlop) {
|
||||
onPull(mViewBeingDragged, y);
|
||||
// Only record the y motion if the user has scrolled down.
|
||||
if (yDx > 0f) {
|
||||
mLastMotionY = y;
|
||||
}
|
||||
} else {
|
||||
onPullEnded();
|
||||
resetTouch();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP: {
|
||||
checkScrollForRefresh(mViewBeingDragged);
|
||||
if (mIsBeingDragged) {
|
||||
onPullEnded();
|
||||
}
|
||||
resetTouch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void minimizeHeader() {
|
||||
if (isDestroyed()) return;
|
||||
|
||||
mHeaderTransformer.onRefreshMinimized();
|
||||
|
||||
if (mHeaderViewListener != null) {
|
||||
mHeaderViewListener.onStateChanged(mHeaderView, HeaderViewListener.STATE_MINIMIZED);
|
||||
}
|
||||
}
|
||||
|
||||
void resetTouch() {
|
||||
mIsBeingDragged = false;
|
||||
mHandlingTouchEventFromDown = false;
|
||||
mInitialMotionY = mLastMotionY = mPullBeginY = -1f;
|
||||
}
|
||||
|
||||
void onPullStarted(float y) {
|
||||
if (DEBUG) {
|
||||
Logger.d(LOG_TAG, "onPullStarted");
|
||||
}
|
||||
showHeaderView();
|
||||
mPullBeginY = y;
|
||||
}
|
||||
|
||||
void onPull(View view, float y) {
|
||||
if (DEBUG) {
|
||||
Logger.d(LOG_TAG, "onPull");
|
||||
}
|
||||
|
||||
final float pxScrollForRefresh = getScrollNeededForRefresh(view);
|
||||
final float scrollLength = y - mPullBeginY;
|
||||
|
||||
if (scrollLength < pxScrollForRefresh) {
|
||||
mHeaderTransformer.onPulled(scrollLength / pxScrollForRefresh);
|
||||
} else {
|
||||
if (mRefreshOnUp) {
|
||||
mHeaderTransformer.onReleaseToRefresh();
|
||||
} else {
|
||||
setRefreshingInt(view, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onPullEnded() {
|
||||
if (DEBUG) {
|
||||
Logger.d(LOG_TAG, "onPullEnded");
|
||||
}
|
||||
if (!mIsRefreshing) {
|
||||
reset(true);
|
||||
}
|
||||
}
|
||||
|
||||
void showHeaderView() {
|
||||
updateHeaderViewPosition(mHeaderView);
|
||||
if (mHeaderTransformer.showHeaderView()) {
|
||||
if (mHeaderViewListener != null) {
|
||||
mHeaderViewListener.onStateChanged(mHeaderView,
|
||||
HeaderViewListener.STATE_VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hideHeaderView() {
|
||||
if (mHeaderTransformer.hideHeaderView()) {
|
||||
if (mHeaderViewListener != null) {
|
||||
mHeaderViewListener.onStateChanged(mHeaderView,
|
||||
HeaderViewListener.STATE_HIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected final Activity getAttachedActivity() {
|
||||
return mActivity;
|
||||
}
|
||||
|
||||
protected EnvironmentDelegate createDefaultEnvironmentDelegate() {
|
||||
return new EnvironmentDelegate() {
|
||||
@Override
|
||||
public Context getContextForInflater(Activity activity) {
|
||||
Context context = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
ActionBar ab = activity.getActionBar();
|
||||
if (ab != null) {
|
||||
context = ab.getThemedContext();
|
||||
}
|
||||
}
|
||||
if (context == null) {
|
||||
context = activity;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected HeaderTransformer createDefaultHeaderTransformer() {
|
||||
return new DefaultHeaderTransformer();
|
||||
}
|
||||
|
||||
private boolean checkScrollForRefresh(View view) {
|
||||
if (mIsBeingDragged && mRefreshOnUp && view != null) {
|
||||
if (mLastMotionY - mPullBeginY >= getScrollNeededForRefresh(view)) {
|
||||
setRefreshingInt(view, true, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setRefreshingInt(View view, boolean refreshing, boolean fromTouch) {
|
||||
if (isDestroyed()) return;
|
||||
|
||||
if (DEBUG) Logger.d(LOG_TAG, "setRefreshingInt: " + refreshing);
|
||||
// Check to see if we need to do anything
|
||||
if (mIsRefreshing == refreshing) {
|
||||
return;
|
||||
}
|
||||
|
||||
resetTouch();
|
||||
|
||||
if (refreshing && canRefresh(fromTouch)) {
|
||||
startRefresh(view, fromTouch);
|
||||
} else {
|
||||
reset(fromTouch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fromTouch Whether this is being invoked from a touch event
|
||||
* @return true if we're currently in a state where a refresh can be
|
||||
* started.
|
||||
*/
|
||||
private boolean canRefresh(boolean fromTouch) {
|
||||
return !mIsRefreshing && (!fromTouch || mOnRefreshListener != null);
|
||||
}
|
||||
|
||||
private float getScrollNeededForRefresh(View view) {
|
||||
return view.getHeight() * mRefreshScrollDistance;
|
||||
}
|
||||
|
||||
private void reset(boolean fromTouch) {
|
||||
// Update isRefreshing state
|
||||
mIsRefreshing = false;
|
||||
|
||||
// Remove any minimize callbacks
|
||||
if (mRefreshMinimize) {
|
||||
getHeaderView().removeCallbacks(mRefreshMinimizeRunnable);
|
||||
}
|
||||
|
||||
// Hide Header View
|
||||
hideHeaderView();
|
||||
}
|
||||
|
||||
private void startRefresh(View view, boolean fromTouch) {
|
||||
// Update isRefreshing state
|
||||
mIsRefreshing = true;
|
||||
|
||||
// Call OnRefreshListener if this call has originated from a touch event
|
||||
if (fromTouch) {
|
||||
if (mOnRefreshListener != null) {
|
||||
mOnRefreshListener.onRefreshStarted(view);
|
||||
}
|
||||
}
|
||||
|
||||
// Call Transformer
|
||||
mHeaderTransformer.onRefreshStarted();
|
||||
|
||||
// Show Header View
|
||||
showHeaderView();
|
||||
|
||||
// Post a runnable to minimize the refresh header
|
||||
if (mRefreshMinimize) {
|
||||
if (mRefreshMinimizeDelay > 0) {
|
||||
getHeaderView().postDelayed(mRefreshMinimizeRunnable, mRefreshMinimizeDelay);
|
||||
} else {
|
||||
getHeaderView().post(mRefreshMinimizeRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDestroyed() {
|
||||
if (mIsDestroyed) {
|
||||
Log.i(LOG_TAG, "PullToRefreshAttacher is destroyed.");
|
||||
}
|
||||
return mIsDestroyed;
|
||||
}
|
||||
|
||||
protected void addHeaderViewToActivity(View headerView) {
|
||||
// Get the Display Rect of the Decor View
|
||||
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(mRect);
|
||||
|
||||
// Honour the requested layout params
|
||||
int width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
int height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
ViewGroup.LayoutParams requestedLp = headerView.getLayoutParams();
|
||||
if (requestedLp != null) {
|
||||
width = requestedLp.width;
|
||||
height = requestedLp.height;
|
||||
}
|
||||
|
||||
// Create LayoutParams for adding the View as a panel
|
||||
WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(width, height,
|
||||
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
wlp.x = 0;
|
||||
wlp.y = mRect.top;
|
||||
wlp.gravity = Gravity.TOP;
|
||||
|
||||
// Workaround for Issue #182
|
||||
headerView.setTag(wlp);
|
||||
mActivity.getWindowManager().addView(headerView, wlp);
|
||||
}
|
||||
|
||||
protected void updateHeaderViewPosition(View headerView) {
|
||||
// Refresh the Display Rect of the Decor View
|
||||
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(mRect);
|
||||
|
||||
WindowManager.LayoutParams wlp = null;
|
||||
if (headerView.getLayoutParams() instanceof WindowManager.LayoutParams) {
|
||||
wlp = (WindowManager.LayoutParams) headerView.getLayoutParams();
|
||||
} else if (headerView.getTag() instanceof WindowManager.LayoutParams) {
|
||||
wlp = (WindowManager.LayoutParams) headerView.getTag();
|
||||
}
|
||||
|
||||
if (wlp != null && wlp.y != mRect.top) {
|
||||
wlp.y = mRect.top;
|
||||
mActivity.getWindowManager().updateViewLayout(headerView, wlp);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeHeaderViewFromActivity(View headerView) {
|
||||
mAddHeaderViewRunnable.finish();
|
||||
|
||||
if (headerView.getWindowToken() != null) {
|
||||
mActivity.getWindowManager().removeViewImmediate(headerView);
|
||||
}
|
||||
}
|
||||
|
||||
private class AddHeaderViewRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isDestroyed()) return;
|
||||
|
||||
if (getDecorView().getWindowToken() != null) {
|
||||
// The Decor View has a Window Token, so we can add the HeaderView!
|
||||
addHeaderViewToActivity(mHeaderView);
|
||||
} else {
|
||||
// The Decor View doesn't have a Window Token yet, post ourselves again...
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
getDecorView().post(this);
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
getDecorView().removeCallbacks(this);
|
||||
}
|
||||
|
||||
private View getDecorView() {
|
||||
return getAttachedActivity().getWindow().getDecorView();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="12dp">
|
||||
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:id="@+id/taskLabel"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text=":"/>
|
||||
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textStyle="bold"
|
||||
android:gravity="right"
|
||||
android:text="2 TASKS"
|
||||
android:id="@+id/taskValue"/>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,41 @@
|
|||
package com.adins.mss.base.models;
|
||||
|
||||
import com.adins.mss.foundation.http.MssRequestType;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Created by adityapurwa on 30/03/15.
|
||||
*/
|
||||
public class ChangePasswordRequestModel extends MssRequestType {
|
||||
@SerializedName("uuid_user")
|
||||
private String uuid_user;
|
||||
@SerializedName("old_password")
|
||||
private String old_password;
|
||||
@SerializedName("new_password")
|
||||
private String new_password;
|
||||
|
||||
public String getUuid_user() {
|
||||
|
||||
return uuid_user;
|
||||
}
|
||||
|
||||
public void setUuid_user(String uuid_user) {
|
||||
this.uuid_user = uuid_user;
|
||||
}
|
||||
|
||||
public String getOld_password() {
|
||||
return old_password;
|
||||
}
|
||||
|
||||
public void setOld_password(String old_password) {
|
||||
this.old_password = old_password;
|
||||
}
|
||||
|
||||
public String getNew_password() {
|
||||
return new_password;
|
||||
}
|
||||
|
||||
public void setNew_password(String new_password) {
|
||||
this.new_password = new_password;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue