增加发现页
1
.idea/gradle.xml
generated
@ -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" />
|
||||
|
@ -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')
|
||||
}
|
@ -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>
|
@ -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]);
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
@ -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)));
|
||||
//使用内存保持cookie,app退出后,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
/**
|
||||
* 设置屏幕横竖屏切换
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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";//任务专区,活动专区
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
10
app/src/main/res/drawable/ic_baseline_arrow.xml
Normal 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>
|
@ -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"
|
||||
|
@ -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>
|
14
app/src/main/res/layout/task_explain_fragment.xml
Normal 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>
|
49
app/src/main/res/layout/task_prefecture_fragment.xml
Normal 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>
|
@ -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>
|
Before Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 320 B |
9
app/src/main/res/values-v19/styles.xml
Normal 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>
|
@ -1,3 +1,5 @@
|
||||
<resources>
|
||||
<!--状态栏-->
|
||||
<dimen name="top_pind_sp">20dp</dimen>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
</resources>
|
4
app/src/main/res/xml/network_security_config.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
</network-security-config>
|
@ -1,2 +1 @@
|
||||
include ':app'
|
||||
rootProject.name = "MyApplication"
|
||||
include ':app', ':xrecyclerview'
|
3
xrecyclerview/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/build
|
||||
*.iml
|
||||
.idea
|
30
xrecyclerview/build.gradle
Normal 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'
|
||||
}
|
||||
|
||||
|
BIN
xrecyclerview/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
xrecyclerview/gradle/wrapper/gradle-wrapper.properties
vendored
Normal 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
@ -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
@ -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
|
8
xrecyclerview/local.properties
Normal 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
@ -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 *;
|
||||
#}
|
@ -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);
|
||||
}
|
||||
}
|
4
xrecyclerview/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jcodecraeer.xrecyclerview">
|
||||
<application/>
|
||||
</manifest>
|
@ -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);
|
||||
}
|
||||
|
@ -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 + "年前";
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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-31,make 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();
|
||||
}
|
||||
}
|
||||
}
|