增加发现页

This commit is contained in:
wds 2021-05-26 17:58:12 +08:00
parent 4b28f19d9a
commit 26d444cbf8
154 changed files with 5933 additions and 99 deletions

1
.idea/gradle.xml generated
View File

@ -12,6 +12,7 @@
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/xrecyclerview" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />

View File

@ -42,9 +42,7 @@ android {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//butterknife依赖
implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
//
//
@ -67,6 +65,9 @@ android {
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
//
//
implementation 'com.github.bumptech.glide:glide:4.8.0'
//xRecyclerview下拉刷新控件
implementation project(':xrecyclerview')
}

View File

@ -1,15 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".activity.HomeActivity"></activity>
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme.NoActionBar"
>
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -18,6 +22,8 @@
</intent-filter>
</activity>
<activity android:name=".activity.LoginActivity"></activity>
<activity android:name=".activity.HomeActivity"></activity>
<activity android:name=".activity.ManagementFragment"></activity>
</application>
</manifest>

View File

@ -54,6 +54,7 @@ public class HomeActivity extends BaseActivity {
fragments.add(new RecordFragment());
fragments.add(new FindFragment());
fragments.add(new MineFragment());
mViewPager.setOffscreenPageLimit(3);
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
@ -66,6 +67,8 @@ public class HomeActivity extends BaseActivity {
return fragments.size();
}
});
mViewPager.setCanScroll(true);
mViewPager.setNoScrollAnim(false);
mTab.setupWithViewPager(mViewPager);
mTab.getTabAt(0).setText(name[0]).setIcon(pic[0]);
mTab.getTabAt(1).setText(name[1]).setIcon(pic1[1]);

View File

@ -1,15 +1,13 @@
package com.example.myapplication.activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.example.myapplication.R;
import com.example.myapplication.base.BaseActivity;
@ -41,9 +39,22 @@ public class MainActivity extends BaseActivity {
}.start();
}
private void initPermission() {
String[] pers = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.INTERNET,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION
};
ActivityCompat.requestPermissions(this, pers, 100);
}
@Override
protected void initView() {
super.initView();
initPermission();
}
}

View File

@ -9,6 +9,8 @@ import com.example.myapplication.base.BaseActivity;
import com.example.myapplication.fragment.FindFragment;
import com.example.myapplication.fragment.MineFragment;
import com.example.myapplication.fragment.RecordFragment;
import com.example.myapplication.fragment.TaskExplainFragment;
import com.example.myapplication.fragment.TaskPrefectureFragment;
import com.example.myapplication.fragment.TreasureFragment;
import com.gyf.immersionbar.ImmersionBar;
@ -28,6 +30,8 @@ public class ManagementFragment extends BaseActivity {
private FindFragment findFragment;//发现的fragment
private RecordFragment recordFragment;//纪录的fragment
private TreasureFragment treasureFragment;//寻宝的fragment
private TaskPrefectureFragment taskPrefectureFragment;//发现-任务专区的fragment
private TaskExplainFragment taskExplainFragment;//发现-任务说明的fragment
@Override
@ -56,6 +60,10 @@ public class ManagementFragment extends BaseActivity {
fragmentTransaction.hide(recordFragment);
if (treasureFragment != null)
fragmentTransaction.hide(treasureFragment);
if (taskPrefectureFragment!=null)
fragmentTransaction.hide(taskPrefectureFragment);
if (taskExplainFragment!=null)
fragmentTransaction.hide(taskExplainFragment);
}
public void selectorFragment(int i) {
@ -97,6 +105,22 @@ public class ManagementFragment extends BaseActivity {
fragmentTransaction.show(treasureFragment);
}
break;
case 7:
if (taskPrefectureFragment==null){
taskPrefectureFragment=new TaskPrefectureFragment();
fragmentTransaction.add(R.id.frame_layout,taskPrefectureFragment);
}else {
fragmentTransaction.show(taskPrefectureFragment);
}
break;
case 8:
if (taskExplainFragment==null){
taskExplainFragment=new TaskExplainFragment();
fragmentTransaction.add(R.id.frame_layout,taskExplainFragment);
}else {
fragmentTransaction.show(taskExplainFragment);
}
break;
}
fragmentTransaction.commit();
@ -118,7 +142,12 @@ public class ManagementFragment extends BaseActivity {
case 4:
treasureFragment.onActivityResult(requestCode, resultCode, data);
break;
case 7:
taskPrefectureFragment.onActivityResult(requestCode, resultCode, data);
break;
case 8:
taskExplainFragment.onActivityResult(requestCode, resultCode, data);
break;
}
}
private void setZtlTextColor() {

View File

@ -2,6 +2,19 @@ package com.example.myapplication.api;
import android.app.Application;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheEntity;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.cookie.CookieJarImpl;
import com.lzy.okgo.cookie.store.DBCookieStore;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.lzy.okgo.model.HttpHeaders;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import okhttp3.OkHttpClient;
public class UserApplication extends Application {
public static UserApplication userApplication;
@ -10,11 +23,49 @@ public class UserApplication extends Application {
public void onCreate() {
super.onCreate();
userApplication=this;
initOkGo();
}
public static UserApplication getUserApplication() {
return userApplication;
}
private void initOkGo() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//log相关
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
//log打印级别决定了log显示的详细程度
loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
//log颜色级别决定了log在控制台显示的颜色
loggingInterceptor.setColorLevel(Level.INFO);
//设置请求头,token值
HttpHeaders headers = new HttpHeaders();
//headers.put("X-Access-Token", SPUtils.get(SpKey.TOKEN, "")+"");
// LogUtils.v("X-Access-Token:" + SPUtils.get(SpKey.TOKEN, ""));
builder.addInterceptor(loggingInterceptor);
//自动管理cookie或者叫session的保持以下几种任选其一就行
//使用sp保持cookie如果cookie不过期则一直有效
//builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));
//使用数据库保持cookie如果cookie不过期则一直有效
builder.cookieJar(new CookieJarImpl(new DBCookieStore(this)));
//使用内存保持cookieapp退出后cookie消失
//builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));
//超时时间设置默认60秒
//全局的读取超时时间
builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
//全局的写入超时时间
builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
//全局的连接超时时间
builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
OkGo.getInstance().init(this)
.setOkHttpClient(builder.build())
//全局统一缓存模式默认不使用缓存可以不传
.setCacheMode(CacheMode.NO_CACHE)
//全局统一缓存时间默认永不过期可以不传
.setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)
//设置公共请求头
.addCommonHeaders(headers)
//全局统一超时重连次数默认为三次那么最差的情况会请求4次(一次原始请求三次重连请求)不需要可以设置为0;
.setRetryCount(0);
}
}

View File

@ -5,9 +5,6 @@ import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
@ -15,16 +12,12 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapplication.R;
import com.example.myapplication.api.UserApplication;
import com.gyf.immersionbar.ImmersionBar;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public abstract class BaseActivity extends AppCompatActivity {
private Unbinder bind;
private AlertDialog alertDialog;
@Override
@ -35,7 +28,7 @@ public abstract class BaseActivity extends AppCompatActivity {
ImmersionBar.with(this).init();
Collector.addActivity(this);
setContentView(getLayout());
bind = ButterKnife.bind(this);
initMVP();
initView();
initData();
@ -91,7 +84,6 @@ public abstract class BaseActivity extends AppCompatActivity {
protected void onDestroy() {
super.onDestroy();
Collector.removeActivity(this);
bind.unbind();
}
/**
* 设置屏幕横竖屏切换

View File

@ -13,23 +13,22 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public abstract class BaseFragment extends Fragment {
private Unbinder bind;
private AlertDialog alertDialog;
public View mView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View inflate = inflater.inflate(getLayout(), container, false);
bind = ButterKnife.bind(this, inflate);
mView = LayoutInflater.from(getActivity()).inflate(getLayout(), container, false);
initMvp();
initView();
initData();
return inflate;
return mView;
}
protected void initMvp() {
@ -75,6 +74,5 @@ public abstract class BaseFragment extends Fragment {
@Override
public void onDestroyView() {
super.onDestroyView();
bind.unbind();
}
}

View File

@ -0,0 +1,38 @@
package com.example.myapplication.bean;
public class ListBean {
/**
* id : 1
* username : kenny
* sex : 6
*/
private int id;
private String username;
private int sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}

View File

@ -0,0 +1,144 @@
package com.example.myapplication.bean;
import java.util.List;
/**
* 任务说明点击
*/
public class TaskSpecificationBean {
/**
* msg : 成功
* body : {"rownum":0,"data":[{"Subtitle":"","createtime":"","src":"http://10.130.23.166:8080/cbt/img/blue.png","id":11,"title":"标题11"},{"Subtitle":"","createtime":"","src":"http://10.130.23.166:8080/cbt/img/blue.png","id":12,"title":"标题12"},{"Subtitle":"","createtime":"","src":"http://10.130.23.166:8080/cbt/img/blue.png","id":13,"title":"标题13"}],"numFound":100,"rows":10}
* status : 0
*/
private String msg;
private BodyBean body;
private int status;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public BodyBean getBody() {
return body;
}
public void setBody(BodyBean body) {
this.body = body;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public static class BodyBean {
/**
* rownum : 0
* data : [{"Subtitle":"","createtime":"","src":"http://10.130.23.166:8080/cbt/img/blue.png","id":11,"title":"标题11"},{"Subtitle":"","createtime":"","src":"http://10.130.23.166:8080/cbt/img/blue.png","id":12,"title":"标题12"},{"Subtitle":"","createtime":"","src":"http://10.130.23.166:8080/cbt/img/blue.png","id":13,"title":"标题13"}]
* numFound : 100
* rows : 10
*/
private int rownum;
private int numFound;
private int rows;
private List<DataBean> data;
public int getRownum() {
return rownum;
}
public void setRownum(int rownum) {
this.rownum = rownum;
}
public int getNumFound() {
return numFound;
}
public void setNumFound(int numFound) {
this.numFound = numFound;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public static class DataBean {
/**
* Subtitle :
* createtime :
* src : http://10.130.23.166:8080/cbt/img/blue.png
* id : 11
* title : 标题11
*/
private String Subtitle;
private String createtime;
private String src;
private int id;
private String title;
public String getSubtitle() {
return Subtitle;
}
public void setSubtitle(String Subtitle) {
this.Subtitle = Subtitle;
}
public String getCreatetime() {
return createtime;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
}
}

View File

@ -0,0 +1,144 @@
package com.example.myapplication.bean;
import java.util.List;
/**
* 任务专区bean
*/
public class TaskZoneBean {
/**
* msg : 成功
* body : {"rownum":0,"data":[{"Subtitle":"说明0","createtime":"2021-05-26 15:33:51","src":"","id":0,"title":"标题0"},{"Subtitle":"说明1","createtime":"2021-05-26 15:33:51","src":"","id":1,"title":"标题1"},{"Subtitle":"说明2","createtime":"2021-05-26 15:33:51","src":"","id":2,"title":"标题2"},{"Subtitle":"说明3","createtime":"2021-05-26 15:33:51","src":"","id":3,"title":"标题3"},{"Subtitle":"说明4","createtime":"2021-05-26 15:33:51","src":"","id":4,"title":"标题4"},{"Subtitle":"说明5","createtime":"2021-05-26 15:33:51","src":"","id":5,"title":"标题5"},{"Subtitle":"说明6","createtime":"2021-05-26 15:33:51","src":"","id":6,"title":"标题6"},{"Subtitle":"说明7","createtime":"2021-05-26 15:33:51","src":"","id":7,"title":"标题7"},{"Subtitle":"说明8","createtime":"2021-05-26 15:33:51","src":"","id":8,"title":"标题8"},{"Subtitle":"说明9","createtime":"2021-05-26 15:33:51","src":"","id":9,"title":"标题9"}],"numFound":100,"rows":10}
* status : 0
*/
private String msg;
private BodyBean body;
private int status;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public BodyBean getBody() {
return body;
}
public void setBody(BodyBean body) {
this.body = body;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public static class BodyBean {
/**
* rownum : 0
* data : [{"Subtitle":"说明0","createtime":"2021-05-26 15:33:51","src":"","id":0,"title":"标题0"},{"Subtitle":"说明1","createtime":"2021-05-26 15:33:51","src":"","id":1,"title":"标题1"},{"Subtitle":"说明2","createtime":"2021-05-26 15:33:51","src":"","id":2,"title":"标题2"},{"Subtitle":"说明3","createtime":"2021-05-26 15:33:51","src":"","id":3,"title":"标题3"},{"Subtitle":"说明4","createtime":"2021-05-26 15:33:51","src":"","id":4,"title":"标题4"},{"Subtitle":"说明5","createtime":"2021-05-26 15:33:51","src":"","id":5,"title":"标题5"},{"Subtitle":"说明6","createtime":"2021-05-26 15:33:51","src":"","id":6,"title":"标题6"},{"Subtitle":"说明7","createtime":"2021-05-26 15:33:51","src":"","id":7,"title":"标题7"},{"Subtitle":"说明8","createtime":"2021-05-26 15:33:51","src":"","id":8,"title":"标题8"},{"Subtitle":"说明9","createtime":"2021-05-26 15:33:51","src":"","id":9,"title":"标题9"}]
* numFound : 100
* rows : 10
*/
private int rownum;
private int numFound;
private int rows;
private List<DataBean> data;
public int getRownum() {
return rownum;
}
public void setRownum(int rownum) {
this.rownum = rownum;
}
public int getNumFound() {
return numFound;
}
public void setNumFound(int numFound) {
this.numFound = numFound;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public static class DataBean {
/**
* Subtitle : 说明0
* createtime : 2021-05-26 15:33:51
* src :
* id : 0
* title : 标题0
*/
private String Subtitle;
private String createtime;
private String src;
private int id;
private String title;
public String getSubtitle() {
return Subtitle;
}
public void setSubtitle(String Subtitle) {
this.Subtitle = Subtitle;
}
public String getCreatetime() {
return createtime;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
}
}

View File

@ -1,13 +1,23 @@
package com.example.myapplication.fragment;
import android.content.Intent;
import android.view.View;
import android.widget.LinearLayout;
import com.example.myapplication.R;
import com.example.myapplication.activity.ManagementFragment;
import com.example.myapplication.base.BaseFragment;
import com.gyf.immersionbar.ImmersionBar;
/**
* 发现的Fragment
* 2021-5-25
*/
public class FindFragment extends BaseFragment {
public class FindFragment extends BaseFragment implements View.OnClickListener{
private LinearLayout linear_task_prefecture;//任务专区
private LinearLayout linear_task_explain;//任务说明
@Override
protected int getLayout() {
return R.layout.find_fragment;
@ -16,10 +26,30 @@ public class FindFragment extends BaseFragment {
@Override
protected void initView() {
super.initView();
linear_task_prefecture = mView.findViewById(R.id.linear_task_prefecture);
linear_task_prefecture.setOnClickListener(this::onClick);
linear_task_explain = mView.findViewById(R.id.linear_task_explain);
linear_task_explain.setOnClickListener(this::onClick);
}
@Override
protected void initData() {
super.initData();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.linear_task_prefecture:
Intent prefectureIntent = new Intent(getActivity(), ManagementFragment.class);
prefectureIntent.putExtra("tag",7);
startActivity(prefectureIntent);
break;
case R.id.linear_task_explain:
Intent explainIntent = new Intent(getActivity(), ManagementFragment.class);
explainIntent.putExtra("tag",8);
startActivity(explainIntent);
break;
}
}
}

View File

@ -2,6 +2,7 @@ package com.example.myapplication.fragment;
import com.example.myapplication.R;
import com.example.myapplication.base.BaseFragment;
import com.gyf.immersionbar.ImmersionBar;
/**
* 我的Fragment

View File

@ -1,12 +1,17 @@
package com.example.myapplication.fragment;
import android.view.Gravity;
import android.util.Log;
import android.widget.Toast;
import com.example.myapplication.R;
import com.example.myapplication.base.BaseFragment;
import com.example.myapplication.bean.ListBean;
import com.example.myapplication.bean.TaskSpecificationBean;
import com.example.myapplication.http.Callback;
import com.example.myapplication.http.HttpInterface;
import com.example.myapplication.http.OkGoBuilder;
import org.json.JSONArray;
import org.json.JSONObject;
/**
@ -21,26 +26,35 @@ public class RecordFragment extends BaseFragment {
@Override
protected void initView() {
super.initView();
JSONObject jsonObject = new JSONObject();
OkGoBuilder.getInstance().Builder(getActivity()).url("")
.method(OkGoBuilder.PSOT)
.json(jsonObject)
.cls(Gravity.class)
.callback(new Callback() {
@Override
public void onSuccess(Object response, int id) {
}
@Override
public void onError(Throwable e, int id) {
}
}).build();
}
//界面可见时再加载数据
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
OkGoBuilder.getInstance()
.Builder(getActivity())
.url(HttpInterface.listTask)
.method(OkGoBuilder.GET)
.cls(TaskSpecificationBean.class)
.json(new JSONObject())
.callback(new Callback<TaskSpecificationBean>() {
@Override
public void onSuccess(TaskSpecificationBean gl, int id) {
Toast.makeText(getActivity(),gl.getMsg()+"sssssssssssssssssss", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e, int id) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("TAG", "onError: "+e.getMessage());
}
}).build();
}
}
@Override
protected void initData() {
super.initData();
}
}
}

View File

@ -0,0 +1,24 @@
package com.example.myapplication.fragment;
import com.example.myapplication.R;
import com.example.myapplication.base.BaseFragment;
/**
* 发现-任务说明
*/
public class TaskExplainFragment extends BaseFragment {
@Override
protected int getLayout() {
return R.layout.task_explain_fragment;
}
@Override
protected void initView() {
super.initView();
}
@Override
protected void initData() {
super.initData();
}
}

View File

@ -0,0 +1,44 @@
package com.example.myapplication.fragment;
import android.view.View;
import android.widget.ImageView;
import com.example.myapplication.R;
import com.example.myapplication.base.BaseFragment;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
/**
* 发现-任务专区
*/
public class TaskPrefectureFragment extends BaseFragment implements View.OnClickListener{
private ImageView mIvFindTask;
private XRecyclerView taskRecycler;
@Override
protected int getLayout() {
return R.layout.task_prefecture_fragment;
}
@Override
protected void initView() {
super.initView();
mIvFindTask = mView.findViewById(R.id.iv_find_task);
mIvFindTask.setOnClickListener(this::onClick);
taskRecycler = mView.findViewById(R.id.task_recycler);
}
@Override
protected void initData() {
super.initData();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_find_task:
getActivity().finish();
break;
}
}
}

View File

@ -1,5 +1,7 @@
package com.example.myapplication.http;
public class HttpInterface {
//http://172.21.91.160:8000/api/user/list
public static final String IP = "http://172.21.91.160:8000/api/1/";
public static final String listTask = IP + "task/list";//任务专区活动专区
}

View File

@ -1,19 +1,21 @@
package com.example.myapplication.http;
import android.app.Activity;
import android.util.Log;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.model.HttpParams;
import com.lzy.okgo.model.Response;
import com.lzy.okgo.request.PostRequest;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.util.ArrayList;
/**
* Created by yzb_android on 2021 5 25
* Created by yzb_android on 2019/12/30.
* 作用OKGO帮助类-建造者模式
*/
@ -44,8 +46,9 @@ public class OkGoBuilder<T> {
* 参数
*/
private HttpParams params;
//private String jsonstr;
private String jsonstr;
private JSONObject json;
private JSONArray jsonArray;
/**
* 实体类
*/
@ -90,6 +93,7 @@ public class OkGoBuilder<T> {
}
public OkGoBuilder url(String url) {
this.url = url;
this.url = url;
return this;
}
@ -98,12 +102,10 @@ public class OkGoBuilder<T> {
this.file = file;
return this;
}
public OkGoBuilder pdf(String pdf) {
this.pdf = pdf;
return this;
}
public OkGoBuilder method(int methodType) {
this.methodType = methodType;
return this;
@ -120,16 +122,19 @@ public class OkGoBuilder<T> {
}
// public OkGoBuilder jsonstr(String jsonstr) {
// this.jsonstr = jsonstr;
// return this;
// }
public OkGoBuilder jsonstr(String jsonstr) {
this.jsonstr = jsonstr;
return this;
}
public OkGoBuilder json(JSONObject json) {
this.json = json;
return this;
}
public OkGoBuilder jsonArray(JSONArray json) {
this.jsonArray = json;
return this;
}
public OkGoBuilder cls(Class<T> clazz) {
this.clazz = clazz;
return this;
@ -223,7 +228,6 @@ public class OkGoBuilder<T> {
}
});
}
/**
* post 发送文件
*/
@ -236,7 +240,7 @@ public class OkGoBuilder<T> {
request.params("file_" + i, list.get(i));
}
}
if (pdf != null) {
if (pdf!=null){
request.params("pdf", new File(pdf));
}
request.execute(new DialogCallback<T>(clazz) {
@ -260,7 +264,7 @@ public class OkGoBuilder<T> {
private void postRequestAloneFile() {
PostRequest<T> request = OkGo.<T>post(url).tag(this)
.params("param", json.toString());
if (file != null) {
if (file!=null){
request.params("file", new File(file));
}
request.execute(new DialogCallback<T>(clazz) {

View File

@ -13,6 +13,8 @@ import androidx.viewpager.widget.ViewPager;
public class NoSlideViewPager extends ViewPager {
// 定义一个是否可以滑动的boolean
private boolean isCanScroll = false;
//定义一个是否可以滑动效果的boolean
private boolean noScrollAnim = false;
public NoSlideViewPager(@NonNull Context context) {
super(context);
@ -21,7 +23,20 @@ public class NoSlideViewPager extends ViewPager {
public NoSlideViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
/**
* 设置是否能左右滑动
* @param canScroll true 不能滑动
*/
public void setCanScroll(boolean canScroll) {
isCanScroll = canScroll;
}
/**
* 设置没有滑动动画
* @param noScrollAnim false 无动画
*/
public void setNoScrollAnim(boolean noScrollAnim) {
this.noScrollAnim = noScrollAnim;
}
// 滑动到指定位置
@Override
@ -29,36 +44,24 @@ public class NoSlideViewPager extends ViewPager {
super.scrollTo(x, y);
}
// 触摸事件
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isCanScroll) {
return super.onTouchEvent(ev);
} else {
return false;
}
public boolean onTouchEvent(MotionEvent arg0) {
return !isCanScroll && super.onTouchEvent(arg0);
}
// 设置当前显示的布局
@Override
public void setCurrentItem(int item) {
super.setCurrentItem(item);
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return !isCanScroll && super.onInterceptTouchEvent(arg0);
}
// 设置当前显示的布局并定义滑动方式
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
super.setCurrentItem(item, smoothScroll);
}
// 拦截触摸事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isCanScroll) {
return super.onInterceptTouchEvent(ev);
} else {
return false;
}
public void setCurrentItem(int item) {
super.setCurrentItem(item,noScrollAnim);
}
}

View File

@ -7,8 +7,8 @@ import org.json.JSONObject;
public class Whetherisempty {
public static String getClfz(String s) throws JSONException {
JSONObject jsonObject = new JSONObject(s);
if (String.valueOf(jsonObject.get("result")).equals("[]") || String.valueOf(jsonObject.get("result")).equals("")) {
jsonObject.put("result", null);
if (String.valueOf(jsonObject.get("body")).equals("[]") || String.valueOf(jsonObject.get("body")).equals("")) {
jsonObject.put("body", null);
return jsonObject.toString();
} else {
return s;

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M11.67,3.87L9.9,2.1 0,12l9.9,9.9 1.77,-1.77L3.54,12z"/>
</vector>

View File

@ -19,6 +19,7 @@
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="6dp"
app:tabRippleColor="@android:color/transparent"
app:tabIndicatorHeight="0dp"
app:tabTextColor="#F0686666"

View File

@ -4,13 +4,177 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
<RelativeLayout
android:id="@+id/rl_find"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发现的Fragment"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#1BA5F1"
android:paddingTop="@dimen/top_pind_sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_find"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:gravity="center"
android:text="发现"
android:textColor="#ffffff"
android:textSize="17sp"
android:layout_marginLeft="16dp"
android:textStyle="bold" />
</RelativeLayout>
<LinearLayout
android:id="@+id/linear1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="15dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toBottomOf="@+id/rl_find">
<ImageView
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:background="#4A4A4A" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:text="最新公告" />
</LinearLayout>
<LinearLayout
android:id="@+id/linear2"
android:layout_width="match_parent"
android:layout_height="150dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear1">
<LinearLayout
android:id="@+id/linear_task_prefecture"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#8E8787"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="任务专区"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/linear_right"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="150dp"
android:orientation="horizontal"
android:background="#D6BFBF"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="活动专区"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/linear3"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="15dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear2">
<ImageView
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:background="#4A4A4A" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:text="帮助中心" />
</LinearLayout>
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ACAAAA"
app:layout_constraintBottom_toTopOf="@+id/linear4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear3" />
<LinearLayout
android:id="@+id/linear4"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view">
<LinearLayout
android:id="@+id/linear_task_explain"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear1">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/ic_launcher"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="任务说明"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/linear_end"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="100dp"
android:orientation="vertical"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear1">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/ic_launcher"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="能力测评"
/>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@mipmap/ic_launcher_round"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/rl_find"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:paddingTop="@dimen/top_pind_sp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_find_task"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:src="@drawable/ic_baseline_arrow"
/>
<TextView
android:id="@+id/tv_find"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@id/iv_find_task"
android:gravity="center"
android:text="任务专区"
android:textColor="#000"
android:textSize="17sp"
android:textStyle="bold" />
</LinearLayout>
<com.jcodecraeer.xrecyclerview.XRecyclerView
android:id="@+id/task_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rl_find" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>

View File

@ -1,3 +1,5 @@
<resources>
<!--状态栏-->
<dimen name="top_pind_sp">20dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

View File

@ -1,2 +1 @@
include ':app'
rootProject.name = "MyApplication"
include ':app', ':xrecyclerview'

3
xrecyclerview/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/build
*.iml
.idea

View File

@ -0,0 +1,30 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 30
buildToolsVersion '30.0.3'
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
compileOnly 'androidx.appcompat:appcompat:1.1.0'
compileOnly 'androidx.recyclerview:recyclerview:1.1.0'
compileOnly 'com.google.android.material:material:1.1.0'
}

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Fri Oct 26 09:51:04 SGT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

172
xrecyclerview/gradlew vendored Normal file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
xrecyclerview/gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,8 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Fri Oct 26 09:51:00 SGT 2018
sdk.dir=F\:\\sdk

17
xrecyclerview/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/jianghejie/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,13 @@
package com.jcodecraeer.xrecyclerview;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jcodecraeer.xrecyclerview">
<application/>
</manifest>

View File

@ -0,0 +1,41 @@
package com.jcodecraeer.xrecyclerview;
import com.google.android.material.appbar.AppBarLayout;
/**
* Created by jianghejie on 16/6/19.
*/
public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
public enum State {
EXPANDED,
COLLAPSED,
IDLE
}
private State mCurrentState = State.IDLE;
@Override
public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (i == 0) {
if (mCurrentState != State.EXPANDED) {
onStateChanged(appBarLayout, State.EXPANDED);
}
mCurrentState = State.EXPANDED;
} else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
if (mCurrentState != State.COLLAPSED) {
onStateChanged(appBarLayout, State.COLLAPSED);
}
mCurrentState = State.COLLAPSED;
} else {
if (mCurrentState != State.IDLE) {
onStateChanged(appBarLayout, State.IDLE);
}
mCurrentState = State.IDLE;
}
}
public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}

View File

@ -0,0 +1,322 @@
package com.jcodecraeer.xrecyclerview;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.jcodecraeer.xrecyclerview.progressindicator.AVLoadingIndicatorView;
import java.util.Date;
public class ArrowRefreshHeader extends LinearLayout implements BaseRefreshHeader {
private static final String XR_REFRESH_KEY = "XR_REFRESH_KEY";
private static final String XR_REFRESH_TIME_KEY = "XR_REFRESH_TIME_KEY";
private LinearLayout mContainer;
private ImageView mArrowImageView;
private SimpleViewSwitcher mProgressBar;
private TextView mStatusTextView;
private int mState = STATE_NORMAL;
private TextView mHeaderTimeView;
private LinearLayout mHeaderRefreshTimeContainer;
private Animation mRotateUpAnim;
private Animation mRotateDownAnim;
private static final int ROTATE_ANIM_DURATION = 180;
public int mMeasuredHeight;
private AVLoadingIndicatorView progressView;
public void destroy(){
mProgressBar = null;
if(progressView != null){
progressView.destroy();
progressView = null;
}
if(mRotateUpAnim != null){
mRotateUpAnim.cancel();
mRotateUpAnim = null;
}
if(mRotateDownAnim != null){
mRotateDownAnim.cancel();
mRotateDownAnim = null;
}
}
public ArrowRefreshHeader(Context context) {
super(context);
initView();
}
/**
* @param context
* @param attrs
*/
public ArrowRefreshHeader(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public void setRefreshTimeVisible(boolean show){
if(mHeaderRefreshTimeContainer != null)
mHeaderRefreshTimeContainer.setVisibility(show?VISIBLE:GONE);
}
private void initView() {
// 初始情况设置下拉刷新view高度为0
mContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(
R.layout.listview_header, null);
mHeaderRefreshTimeContainer
= (LinearLayout) mContainer.findViewById(R.id.header_refresh_time_container);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(0, 0, 0, 0);
this.setLayoutParams(lp);
this.setPadding(0, 0, 0, 0);
addView(mContainer, new LayoutParams(LayoutParams.MATCH_PARENT, 0));
setGravity(Gravity.BOTTOM);
mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow);
mStatusTextView = (TextView)findViewById(R.id.refresh_status_textview);
//init the progress view
mProgressBar = (SimpleViewSwitcher)findViewById(R.id.listview_header_progressbar);
progressView = new AVLoadingIndicatorView(getContext());
progressView.setIndicatorColor(0xffB5B5B5);
progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader);
if(mProgressBar != null)
mProgressBar.setView(progressView);
mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateUpAnim.setFillAfter(true);
mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateDownAnim.setFillAfter(true);
mHeaderTimeView = (TextView)findViewById(R.id.last_refresh_time);
measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
mMeasuredHeight = getMeasuredHeight();
}
public void setProgressStyle(int style) {
if(style == ProgressStyle.SysProgress){
if(mProgressBar != null)
mProgressBar.setView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyle));
}else{
progressView = new AVLoadingIndicatorView(this.getContext());
progressView.setIndicatorColor(0xffB5B5B5);
progressView.setIndicatorId(style);
mProgressBar.setView(progressView);
}
}
public void setArrowImageView(int resid){
mArrowImageView.setImageResource(resid);
}
public void setState(int state) {
if (state == mState) return ;
if (state == STATE_REFRESHING) { // 显示进度
mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(View.INVISIBLE);
if(mProgressBar != null)
mProgressBar.setVisibility(View.VISIBLE);
smoothScrollTo(mMeasuredHeight);
} else if(state == STATE_DONE) {
mArrowImageView.setVisibility(View.INVISIBLE);
if(mProgressBar != null)
mProgressBar.setVisibility(View.INVISIBLE);
} else { // 显示箭头图片
mArrowImageView.setVisibility(View.VISIBLE);
if(mProgressBar != null){
mProgressBar.setVisibility(View.INVISIBLE);
}
}
mHeaderTimeView.setText(friendlyTime(getLastRefreshTime()));
switch(state){
case STATE_NORMAL:
if (mState == STATE_RELEASE_TO_REFRESH) {
mArrowImageView.startAnimation(mRotateDownAnim);
}
if (mState == STATE_REFRESHING) {
mArrowImageView.clearAnimation();
}
mStatusTextView.setText(R.string.listview_header_hint_normal);
break;
case STATE_RELEASE_TO_REFRESH:
if (mState != STATE_RELEASE_TO_REFRESH) {
mArrowImageView.clearAnimation();
mArrowImageView.startAnimation(mRotateUpAnim);
mStatusTextView.setText(R.string.listview_header_hint_release);
}
break;
case STATE_REFRESHING:
mStatusTextView.setText(R.string.refreshing);
break;
case STATE_DONE:
mStatusTextView.setText(R.string.refresh_done);
break;
default:
}
mState = state;
}
public int getState() {
return mState;
}
private long getLastRefreshTime(){
SharedPreferences s =
getContext()
.getSharedPreferences(XR_REFRESH_KEY,Context.MODE_APPEND);
return s.getLong(XR_REFRESH_TIME_KEY,new Date().getTime());
}
private void saveLastRefreshTime(long refreshTime){
SharedPreferences s =
getContext()
.getSharedPreferences(XR_REFRESH_KEY,Context.MODE_APPEND);
s.edit().putLong(XR_REFRESH_TIME_KEY,refreshTime).commit();
}
@Override
public void refreshComplete(){
mHeaderTimeView.setText(friendlyTime(getLastRefreshTime()));
saveLastRefreshTime(System.currentTimeMillis());
setState(STATE_DONE);
new Handler().postDelayed(new Runnable(){
public void run() {
reset();
}
}, 200);
}
public void setVisibleHeight(int height) {
if (height < 0) height = 0;
LayoutParams lp = (LayoutParams) mContainer .getLayoutParams();
lp.height = height;
mContainer.setLayoutParams(lp);
}
public int getVisibleHeight() {
LayoutParams lp = (LayoutParams) mContainer.getLayoutParams();
return lp.height;
}
@Override
public void onMove(float delta) {
if(getVisibleHeight() > 0 || delta > 0) {
setVisibleHeight((int) delta + getVisibleHeight());
if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态更新箭头
if (getVisibleHeight() > mMeasuredHeight) {
setState(STATE_RELEASE_TO_REFRESH);
}else {
setState(STATE_NORMAL);
}
}
}
}
@Override
public boolean releaseAction() {
boolean isOnRefresh = false;
int height = getVisibleHeight();
if (height == 0) // not visible.
isOnRefresh = false;
if(getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING){
setState(STATE_REFRESHING);
isOnRefresh = true;
}
// refreshing and header isn't shown fully. do nothing.
if (mState == STATE_REFRESHING && height <= mMeasuredHeight) {
//return;
}
if (mState != STATE_REFRESHING) {
smoothScrollTo(0);
}
if (mState == STATE_REFRESHING) {
int destHeight = mMeasuredHeight;
smoothScrollTo(destHeight);
}
return isOnRefresh;
}
public void reset() {
smoothScrollTo(0);
new Handler().postDelayed(new Runnable() {
public void run() {
setState(STATE_NORMAL);
}
}, 500);
}
private void smoothScrollTo(int destHeight) {
ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), destHeight);
animator.setDuration(300).start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
setVisibleHeight((int) animation.getAnimatedValue());
}
});
animator.start();
}
public static String friendlyTime(Date time) {
return friendlyTime(time.getTime());
}
public static String friendlyTime(long time) {
//获取time距离当前的秒数
int ct = (int)((System.currentTimeMillis() - time)/1000);
if(ct == 0) {
return "刚刚";
}
if(ct > 0 && ct < 60) {
return ct + "秒前";
}
if(ct >= 60 && ct < 3600) {
return Math.max(ct / 60,1) + "分钟前";
}
if(ct >= 3600 && ct < 86400)
return ct / 3600 + "小时前";
if(ct >= 86400 && ct < 2592000){ //86400 * 30
int day = ct / 86400 ;
return day + "天前";
}
if(ct >= 2592000 && ct < 31104000) { //86400 * 30
return ct / 2592000 + "月前";
}
return ct / 31104000 + "年前";
}
}

View File

@ -0,0 +1,19 @@
package com.jcodecraeer.xrecyclerview;
/**
* Created by jianghejie on 15/11/22.
*/
interface BaseRefreshHeader {
int STATE_NORMAL = 0;
int STATE_RELEASE_TO_REFRESH = 1;
int STATE_REFRESHING = 2;
int STATE_DONE = 3;
void onMove(float delta);
boolean releaseAction();
void refreshComplete();
}

View File

@ -0,0 +1,21 @@
package com.jcodecraeer.xrecyclerview;
import android.view.View;
/**
* 作者林冠宏
* <p>
* My GitHub : https://github.com/af913337456/
* <p>
* My Blog : http://www.cnblogs.com/linguanh/
* <p>
* on 2017/11/8.
*/
public interface CustomFooterViewCallBack {
void onLoadingMore(View yourFooterView);
void onLoadMoreComplete(View yourFooterView);
void onSetNoMore(View yourFooterView,boolean noMore);
}

View File

@ -0,0 +1,38 @@
package com.jcodecraeer.xrecyclerview;
/**
* Created by jianghejie on 16/6/20.
*/
public interface ItemTouchHelperAdapter {
/**
* Called when an item has been dragged far enough to trigger a move. This is called every time
* an item is shifted, and <strong>not</strong> at the end of a "drop" event.<br/>
* <br/>
* Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after
* adjusting the underlying data to reflect this move.
*
* @param fromPosition The start position of the moved item.
* @param toPosition Then resolved position of the moved item.
*
* @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
* @see RecyclerView.ViewHolder#getAdapterPosition()
*/
void onItemMove(int fromPosition, int toPosition);
/**
* Called when an item has been dismissed by a swipe.<br/>
* <br/>
* Implementations should call {@link RecyclerView.Adapter#notifyItemRemoved(int)} after
* adjusting the underlying data to reflect this removal.
*
* @param position The position of the item dismissed.
*
* @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
* @see RecyclerView.ViewHolder#getAdapterPosition()
*/
void onItemDismiss(int position);
}

View File

@ -0,0 +1,108 @@
package com.jcodecraeer.xrecyclerview;
/**
* Created by jianghejie on 15/11/22.
*/
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class JellyView extends View implements BaseRefreshHeader{
Path path;
Paint paint;
private int minimumHeight = 0;
private int jellyHeight =0;
public JellyView(Context context) {
super(context);
init();
}
public JellyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public JellyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@SuppressWarnings("unused")
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public JellyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
if (isInEditMode()) {
return;
}
path = new Path();
paint = new Paint();
paint.setColor(getContext().getResources().getColor(android.R.color.holo_blue_bright));
paint.setAntiAlias(true);
}
public void setJellyColor(int jellyColor) {
paint.setColor(jellyColor);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
path.lineTo(0, minimumHeight);
path.quadTo(getMeasuredWidth() / 2, minimumHeight + jellyHeight, getMeasuredWidth(), minimumHeight);
path.lineTo(getMeasuredWidth(), 0);
canvas.drawPath(path, paint);
}
@Override
public void setMinimumHeight(int minimumHeight) {
this.minimumHeight = minimumHeight;
}
public void setJellyHeight(int ribbonHeight) {
this.jellyHeight = ribbonHeight;
}
@Override
public int getMinimumHeight() {
return minimumHeight;
}
public int getJellyHeight() {
return jellyHeight;
}
@Override
public void refreshComplete(){
}
@Override
public void onMove(float delta) {
jellyHeight = jellyHeight + (int)delta;
Log.i("jellyHeight", "delta = " + delta);
this.invalidate();
}
@Override
public boolean releaseAction() {
return false;
}
}

View File

@ -0,0 +1,127 @@
package com.jcodecraeer.xrecyclerview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.jcodecraeer.xrecyclerview.progressindicator.AVLoadingIndicatorView;
import androidx.recyclerview.widget.RecyclerView;
public class LoadingMoreFooter extends LinearLayout {
private SimpleViewSwitcher progressCon;
public final static int STATE_LOADING = 0;
public final static int STATE_COMPLETE = 1;
public final static int STATE_NOMORE = 2;
private TextView mText;
private String loadingHint;
private String noMoreHint;
private String loadingDoneHint;
private AVLoadingIndicatorView progressView;
public LoadingMoreFooter(Context context) {
super(context);
initView();
}
/**
* @param context
* @param attrs
*/
public LoadingMoreFooter(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public void destroy(){
progressCon = null;
if(progressView != null){
progressView.destroy();
progressView = null;
}
}
public void setLoadingHint(String hint) {
loadingHint = hint;
}
public void setNoMoreHint(String hint) {
noMoreHint = hint;
}
public void setLoadingDoneHint(String hint) {
loadingDoneHint = hint;
}
public void initView(){
setGravity(Gravity.CENTER);
setLayoutParams(new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
progressCon = new SimpleViewSwitcher(getContext());
progressCon.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
progressView = new AVLoadingIndicatorView(this.getContext());
progressView.setIndicatorColor(0xffB5B5B5);
progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader);
progressCon.setView(progressView);
addView(progressCon);
mText = new TextView(getContext());
mText.setText(getContext().getString(R.string.listview_loading));
if(loadingHint == null || loadingHint.equals("")){
loadingHint = (String)getContext().getText(R.string.listview_loading);
}
if(noMoreHint == null || noMoreHint.equals("")){
noMoreHint = (String)getContext().getText(R.string.nomore_loading);
}
if(loadingDoneHint == null || loadingDoneHint.equals("")){
loadingDoneHint = (String)getContext().getText(R.string.loading_done);
}
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins( (int)getResources().getDimension(R.dimen.textandiconmargin),0,0,0 );
mText.setLayoutParams(layoutParams);
addView(mText);
}
public void setProgressStyle(int style) {
if(style == ProgressStyle.SysProgress){
progressCon.setView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyle));
}else{
progressView = new AVLoadingIndicatorView(this.getContext());
progressView.setIndicatorColor(0xffB5B5B5);
progressView.setIndicatorId(style);
progressCon.setView(progressView);
}
}
public void setState(int state) {
switch(state) {
case STATE_LOADING:
progressCon.setVisibility(View.VISIBLE);
mText.setText(loadingHint);
this.setVisibility(View.VISIBLE);
break;
case STATE_COMPLETE:
mText.setText(loadingDoneHint);
this.setVisibility(View.GONE);
break;
case STATE_NOMORE:
mText.setText(noMoreHint);
progressCon.setVisibility(View.GONE);
this.setVisibility(View.VISIBLE);
break;
}
}
}

View File

@ -0,0 +1,36 @@
package com.jcodecraeer.xrecyclerview;
/**
* Created by jianghejie on 15/11/23.
*/
public class ProgressStyle {
public static final int SysProgress=-1;
public static final int BallPulse=0;
public static final int BallGridPulse=1;
public static final int BallClipRotate=2;
public static final int BallClipRotatePulse=3;
public static final int SquareSpin=4;
public static final int BallClipRotateMultiple=5;
public static final int BallPulseRise=6;
public static final int BallRotate=7;
public static final int CubeTransition=8;
public static final int BallZigZag=9;
public static final int BallZigZagDeflect=10;
public static final int BallTrianglePath=11;
public static final int BallScale=12;
public static final int LineScale=13;
public static final int LineScaleParty=14;
public static final int BallScaleMultiple=15;
public static final int BallPulseSync=16;
public static final int BallBeat=17;
public static final int LineScalePulseOut=18;
public static final int LineScalePulseOutRapid=19;
public static final int BallScaleRipple=20;
public static final int BallScaleRippleMultiple=21;
public static final int BallSpinFadeLoader=22;
public static final int LineSpinFadeLoader=23;
public static final int TriangleSkewSpin=24;
public static final int Pacman=25;
public static final int BallGridBeat=26;
public static final int SemiCircleSpin=27;
}

View File

@ -0,0 +1,88 @@
package com.jcodecraeer.xrecyclerview;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.View;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by jianghejie on 16/6/20.
*/
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
public static final float ALPHA_FULL = 1.0f;
private final ItemTouchHelperAdapter mAdapter;
private XRecyclerView mXrecyclerView;
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter, XRecyclerView recyclerView) {
mAdapter = adapter;
this.mXrecyclerView = recyclerView;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// Enable drag and swipe in both directions
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (source.getItemViewType() != target.getItemViewType()) {
return false;
}
// Notify the adapter of the move
mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
// Notify the adapter of the dismissal
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
// Fade out the view as it is swiped out of the parent's bounds
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
View itemView = viewHolder.itemView;
final float alpha = ALPHA_FULL - Math.abs(dX) / (float) itemView.getWidth();
itemView.setAlpha(alpha);
}
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
// Let the view holder know that this item is being moved or dragged
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setAlpha(ALPHA_FULL);
viewHolder.itemView.setBackgroundColor(0);
}
}

View File

@ -0,0 +1,60 @@
package com.jcodecraeer.xrecyclerview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by jianghejie on 15/11/22.
*/
public class SimpleViewSwitcher extends ViewGroup {
public SimpleViewSwitcher(Context context) {
super(context);
}
public SimpleViewSwitcher(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SimpleViewSwitcher(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = this.getChildCount();
int maxHeight = 0;
int maxWidth = 0;
for (int i = 0; i < childCount; i++) {
View child = this.getChildAt(i);
this.measureChild(child, widthMeasureSpec, heightMeasureSpec);
int cw = child.getMeasuredWidth();
// int ch = child.getMeasuredHeight();
maxWidth = child.getMeasuredWidth();
maxHeight = child.getMeasuredHeight();
}
setMeasuredDimension(maxWidth, maxHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
child.layout(0, 0, r - l, b - t);
}
}
}
public void setView(View view) {
if (this.getChildCount() != 0){
this.removeViewAt(0);
}
this.addView(view,0);
}
}

View File

@ -0,0 +1,292 @@
package com.jcodecraeer.xrecyclerview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.OverScroller;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.NestedScrollingParent;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
/**
* 作者林冠宏
* <p>
* My GitHub : https://github.com/af913337456/
* <p>
* My Blog : http://www.cnblogs.com/linguanh/
* <p>
* on 2017/12/31.
*
* DES:
* A LinearLayout which can combine with XRecyclerView in a sticky scroll status.
*
* Demo: see it in gitHub.
*
* Read_me:
* Only support XRecyclerView for now,if you wanna to support other viewGroups which
* has imp NestedScrollingChild interface,you can change my code,then it will be ok.
* When you use it to XR,you best close pull refresh model,because it may
* cause some new problems that i never met.
* ----LinGuanHong
*/
public class StickyScrollLinearLayout
extends LinearLayout
implements NestedScrollingParent
{
private static final String TAG = "StickyScrollLayout";
private View mTopView;
private View mTabView;
private View mContentView;
private OverScroller mScroller;
private VelocityTracker mVelocityTracker;
private int mTopViewHeight;
private RecyclerView.LayoutManager layoutManager = null;
private int targetFirstVisiblePosition = 1;
public interface StickyScrollInitInterface{
View setTopView();
View setTabView();
View setContentView();
}
public StickyScrollLinearLayout(Context context) {
super(context);
init(context);
}
public StickyScrollLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
setOrientation(LinearLayout.VERTICAL);
mScroller = new OverScroller(context);
}
@SuppressWarnings("all")
public void setInitInterface(@NonNull StickyScrollInitInterface initInterface){
if(initInterface == null)
throw new NullPointerException("initInterface can not be null!");
this.mTopView = initInterface.setTopView();
if(this.mTopView != null)
getTopViewHeight();
this.mTabView = initInterface.setTabView();
this.mContentView = initInterface.setContentView();
if(this.mContentView == null)
return;
setTotalHeight();
requestLayout();
}
public View getContentView(){
return this.mContentView;
}
// 设置 XR 里面显示的 item 第一个的位置是多少时触发拦截
// to set a position of XR's dataList to control when we should call over scroll
public void setTargetFirstVisiblePosition(int targetFirstVisiblePosition) {
this.targetFirstVisiblePosition = targetFirstVisiblePosition;
}
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
Log.e(TAG, "onStartNestedScroll "+child.toString()+" "+target.toString());
return true;
}
@Override
public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) {
Log.e(TAG, "onNestedScrollAccepted");
}
@Override
public void onStopNestedScroll(View target) {
Log.e(TAG, "onStopNestedScroll "+target.toString());
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
Log.e(TAG, "onNestedScroll "+dyConsumed+"----"+dyUnconsumed);
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
if(!(target instanceof XRecyclerView))
// todo 2017-12-31make it more general
throw new UnsupportedOperationException("insert your content must is XRecyclerView!");
layoutManager = ((RecyclerView)target).getLayoutManager();
int firstVisiblePosition;
if (layoutManager instanceof GridLayoutManager) {
firstVisiblePosition = ((GridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
((StaggeredGridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPositions(into);
firstVisiblePosition = into[0];
} else {
firstVisiblePosition = ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition();
}
if(firstVisiblePosition < 0)
return;
int scrollY = getScrollY();
boolean temp = dy > 0 && (scrollY < mTopViewHeight);
Log.e(TAG,
"mTopViewHeight == "+mTopViewHeight
+"\ndy == "+dy
+"\nscrollY == "+scrollY
+"\nhiddenTop && showTop "+temp);
if(!temp){
// judge
temp = dy < 0
&& (scrollY >= 0)
&&
(
!ViewCompat.canScrollVertically(target, -1)
||
firstVisiblePosition==targetFirstVisiblePosition
);
Log.e(TAG,
"mTopViewHeight == "+mTopViewHeight
+"\ndy == "+dy
+"\nscrollY == "+scrollY
+"\nfirstVisiblePosition "+firstVisiblePosition);
}
if (temp) {
scrollBy(0, dy);
consumed[1] = dy;
}
}
@Override
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
Log.e(TAG, "onNestedFling");
return false;
}
@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
Log.e(TAG, "onNestedPreFling");
//down - //up+
if (getScrollY() >= mTopViewHeight) return false;
fling((int) velocityY);
return true;
}
@Override
public int getNestedScrollAxes() {
Log.e(TAG, "getNestedScrollAxes");
return 0;
}
@Deprecated
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
}
// call this when destroy
public void destroy() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// 你可以在 xml 文件内配置
// you can init those views in your xml file
// mTopView = findViewById(R.id.topContainer);
// mTabView = findViewById(R.id.tabLayout);
// mContentView = findViewById(R.id.vp);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(mTabView == null || mTopView == null || mContentView == null)
return;
// getChildAt(0).
// measure(
// widthMeasureSpec,
// MeasureSpec.makeMeasureSpec(
// 0,
// MeasureSpec.UNSPECIFIED
// )
// );
setTotalHeight();
}
private void setTotalHeight(){
ViewGroup.LayoutParams params = mContentView.getLayoutParams();
params.height = getMeasuredHeight() - mTabView.getMeasuredHeight();
setMeasuredDimension(
getMeasuredWidth(),
mTopView.getMeasuredHeight()
+ mTabView.getMeasuredHeight()
+ mContentView.getMeasuredHeight()
);
}
private void getTopViewHeight(){
if(mTopView == null)
return;
mTopViewHeight = mTopView.getMeasuredHeight();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
getTopViewHeight();
}
public void fling(int velocityY) {
mScroller.fling(0, getScrollY(), 0, velocityY, 0, 0, 0, mTopViewHeight);
invalidate();
}
@Override
public void scrollTo(int x, int y) {
if (y < 0)
y = 0;
if (y > mTopViewHeight)
// 边界限制防止把 tabView 也挡住了
// Prevent it from hiding the tabView,so we limit it
y = mTopViewHeight;
if (y != getScrollY())
super.scrollTo(x, y);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(0, mScroller.getCurrY());
invalidate();
}
}
}

Some files were not shown because too many files have changed in this diff Show More