Skip to content

Commit bb77ab6

Browse files
committed
Changes
1 parent 6146c43 commit bb77ab6

16 files changed

+654
-305
lines changed

.idea/other.xml

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ dependencies {
3535
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
3636
implementation 'com.jinrishici:android-sdk:1.5'
3737
implementation 'com.github.bumptech.glide:glide:4.12.0'
38+
implementation libs.swiperefreshlayout
3839
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
3940
implementation libs.appcompat
4041
implementation libs.material

app/src/main/java/com/example/one/FirstFragment.java

Lines changed: 152 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import static androidx.core.app.ActivityCompat.finishAffinity;
44

5+
import android.annotation.SuppressLint;
56
import android.os.Bundle;
7+
import android.view.GestureDetector;
68
import android.view.LayoutInflater;
9+
import android.view.MotionEvent;
710
import android.view.View;
811
import android.view.ViewGroup;
912
import android.widget.TextView;
@@ -12,8 +15,11 @@
1215
import android.widget.ProgressBar;
1316

1417
import androidx.annotation.NonNull;
18+
import androidx.annotation.Nullable;
1519
import androidx.fragment.app.Fragment;
20+
import androidx.navigation.NavOptions;
1621
import androidx.navigation.fragment.NavHostFragment;
22+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
1723

1824
import com.example.one.databinding.FragmentFirstBinding;
1925

@@ -22,15 +28,18 @@
2228
import okhttp3.OkHttpClient;
2329
import okhttp3.Request;
2430
import okhttp3.Response;
31+
2532
import org.json.JSONObject;
33+
2634
import java.io.IOException;
2735

2836
import android.util.Log;
37+
2938
import java.nio.charset.StandardCharsets;
3039

3140
import android.os.CountDownTimer;
3241

33-
public class FirstFragment extends Fragment {
42+
public class FirstFragment extends Fragment implements GestureDetector.OnGestureListener { // 实现 OnGestureListener 接口
3443

3544
private FragmentFirstBinding binding;
3645
private OkHttpClient client = new OkHttpClient();
@@ -39,17 +48,37 @@ public class FirstFragment extends Fragment {
3948
private TextView hitokotoFrom;
4049
private TextView hitokotoFromWho;
4150

42-
private ProgressBar progressBarCountdown;
43-
private Button buttonToggle;
44-
private boolean isAutoFetchEnabled = false;
45-
private CountDownTimer countDownTimer;
51+
// private ProgressBar progressBarCountdown;
52+
// private Button buttonToggle;
53+
// private boolean isAutoFetchEnabled = false;
54+
// private CountDownTimer countDownTimer;
55+
56+
57+
private androidx.swiperefreshlayout.widget.SwipeRefreshLayout swipeRefreshLayout;
58+
private GestureDetector gestureDetector;
59+
60+
private static final int SWIPE_THRESHOLD = 50;
61+
private static final int SWIPE_VELOCITY_THRESHOLD = 50;
4662

4763
@Override
4864
public View onCreateView(
4965
@NonNull LayoutInflater inflater, ViewGroup container,
5066
Bundle savedInstanceState
5167
) {
5268
binding = FragmentFirstBinding.inflate(inflater, container, false);
69+
70+
// 获取 SwipeRefreshLayout 实例
71+
swipeRefreshLayout = binding.getRoot().findViewById(R.id.swipeRefreshLayout1); // Assuming you added SwipeRefreshLayout in your XML
72+
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
73+
@Override
74+
public void onRefresh() {
75+
// This method is called when the user pulls down to refresh
76+
// Perform the refresh operation here
77+
fetchHitokoto();
78+
}
79+
});
80+
81+
5382
return binding.getRoot();
5483
}
5584

@@ -61,66 +90,76 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
6190
hitokotoType = binding.hitokotoType;
6291
hitokotoFrom = binding.hitokotoFrom;
6392
hitokotoFromWho = binding.hitokotoFromWho;
64-
progressBarCountdown = view.findViewById(R.id.progressBar_auto_1);
65-
buttonToggle = view.findViewById(R.id.button_auto_1);
66-
6793

68-
binding.buttonSecond1.setOnClickListener(v ->
69-
NavHostFragment.findNavController(FirstFragment.this)
70-
.navigate(R.id.action_to_SecondFragment)
71-
);
7294

73-
binding.buttonThird1.setOnClickListener(v ->
74-
NavHostFragment.findNavController(FirstFragment.this)
75-
.navigate(R.id.action_to_ThirdFragment)
76-
);
77-
78-
binding.buttonClose1.setOnClickListener(v ->{
79-
finishAffinity(getActivity());
80-
System.exit(0);
95+
gestureDetector = new GestureDetector(getContext(), (GestureDetector.OnGestureListener) this);
96+
view.setOnTouchListener((v, event) -> {
97+
gestureDetector.onTouchEvent(event);
98+
return true;
8199
});
82100

83-
binding.buttonFresh1.setOnClickListener(v ->
84-
fetchHitokoto()
85-
);
86-
87-
buttonToggle.setOnClickListener(v -> {
88-
isAutoFetchEnabled = !isAutoFetchEnabled;
89-
if (isAutoFetchEnabled) {
90-
buttonToggle.setText(R.string.stop);
91-
startAutoFetch();
92-
} else {
93-
buttonToggle.setText(R.string.auto);
94-
stopAutoFetch();
95-
}
96-
});
97101

98102
fetchHitokoto();
99-
}
100-
101-
private void startAutoFetch() {
102-
countDownTimer = new CountDownTimer(5000, 50) {
103-
@Override
104-
public void onTick(long millisUntilFinished) {
105-
int progress = (int) (100 - millisUntilFinished / 50);
106-
progressBarCountdown.setProgress(progress);
107-
}
108103

109-
@Override
110-
public void onFinish() {
111-
fetchHitokoto();
112-
if (isAutoFetchEnabled) {
113-
startAutoFetch();
114-
}
115-
}
116-
}.start();
104+
// progressBarCountdown = view.findViewById(R.id.progressBar_auto_1);
105+
// buttonToggle = view.findViewById(R.id.button_auto_1);
106+
107+
//
108+
// binding.buttonSecond1.setOnClickListener(v ->
109+
// NavHostFragment.findNavController(FirstFragment.this)
110+
// .navigate(R.id.action_to_SecondFragment)
111+
// );
112+
//
113+
// binding.buttonThird1.setOnClickListener(v ->
114+
// NavHostFragment.findNavController(FirstFragment.this)
115+
// .navigate(R.id.action_to_ThirdFragment)
116+
// );
117+
//
118+
// binding.buttonClose1.setOnClickListener(v ->{
119+
// finishAffinity(getActivity());
120+
// System.exit(0);
121+
// });
122+
//
123+
// binding.buttonFresh1.setOnClickListener(v ->
124+
// fetchHitokoto()
125+
// );
126+
127+
// buttonToggle.setOnClickListener(v -> {
128+
// isAutoFetchEnabled = !isAutoFetchEnabled;
129+
// if (isAutoFetchEnabled) {
130+
// buttonToggle.setText(R.string.stop);
131+
// startAutoFetch();
132+
// } else {
133+
// buttonToggle.setText(R.string.auto);
134+
// stopAutoFetch();
135+
// }
136+
// });
117137
}
118138

119-
private void stopAutoFetch() {
120-
if (countDownTimer != null) {
121-
countDownTimer.cancel();
122-
}
123-
}
139+
// private void startAutoFetch() {
140+
// countDownTimer = new CountDownTimer(5000, 50) {
141+
// @Override
142+
// public void onTick(long millisUntilFinished) {
143+
// int progress = (int) (100 - millisUntilFinished / 50);
144+
// progressBarCountdown.setProgress(progress);
145+
// }
146+
//
147+
// @Override
148+
// public void onFinish() {
149+
// fetchHitokoto();
150+
// if (isAutoFetchEnabled) {
151+
// startAutoFetch();
152+
// }
153+
// }
154+
// }.start();
155+
// }
156+
//
157+
// private void stopAutoFetch() {
158+
// if (countDownTimer != null) {
159+
// countDownTimer.cancel();
160+
// }
161+
// }
162+
124163

125164
private void fetchHitokoto() {
126165
Request request = new Request.Builder()
@@ -150,9 +189,11 @@ public void onResponse(Call call, Response response) throws IOException {
150189

151190
hitokotoFrom.setText(json.has("from") && !json.isNull("from") ? json.getString("from") : "");
152191
hitokotoFromWho.setText(json.has("from_who") && !json.isNull("from_who") ? json.getString("from_who") : "");
153-
192+
swipeRefreshLayout.setRefreshing(false);
154193
} catch (Exception e) {
155194
e.printStackTrace();
195+
hitokotoText.setText("Error: " + e.getMessage());
196+
swipeRefreshLayout.setRefreshing(false);
156197
}
157198
});
158199
}
@@ -196,9 +237,63 @@ private void renderTextViewByType(TextView textView, String type) {
196237
textView.setText(description);
197238
}
198239

240+
199241
@Override
200242
public void onDestroyView() {
201243
super.onDestroyView();
202244
binding = null;
203245
}
246+
247+
@Override
248+
public boolean onDown(@NonNull MotionEvent motionEvent) {
249+
return false;
250+
}
251+
252+
@Override
253+
public void onShowPress(@NonNull MotionEvent motionEvent) {
254+
255+
}
256+
257+
@Override
258+
public boolean onSingleTapUp(@NonNull MotionEvent motionEvent) {
259+
return false;
260+
}
261+
262+
@Override
263+
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
264+
// Check if SwipeRefreshLayout is not refreshing
265+
if (!swipeRefreshLayout.isRefreshing()) {
266+
// Check if the scroll is primarily vertical
267+
if (Math.abs(distanceY) > Math.abs(distanceX)) {
268+
// Check if the scroll distance is significant enough to be considered a pull-down gesture
269+
if (distanceY < -SWIPE_THRESHOLD) {
270+
// Handle pull-down gesture for refreshing
271+
swipeRefreshLayout.setRefreshing(true);
272+
fetchHitokoto();
273+
return true;
274+
}
275+
}
276+
}
277+
// Handle regular scroll gesture
278+
return false;
279+
}
280+
281+
@Override
282+
public void onLongPress(MotionEvent e) {
283+
}
284+
285+
286+
@Override
287+
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
288+
if (e1.getX() - e2.getX() > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
289+
// 向左滑动
290+
NavHostFragment.findNavController(this)
291+
.navigate(R.id.action_to_SecondFragment, null, new NavOptions.Builder().setPopUpTo(R.id.FirstFragment, true).build());
292+
} else if (e2.getX() - e1.getX() > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
293+
// 向右滑动
294+
NavHostFragment.findNavController(this)
295+
.navigate(R.id.action_to_ThirdFragment, null, new NavOptions.Builder().setPopUpTo(R.id.FirstFragment, true).build());
296+
}
297+
return true; // 返回 true 表示事件已处理
298+
}
204299
}

app/src/main/java/com/example/one/MainActivity.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import android.os.Bundle;
44
import android.view.Menu;
55

6+
import androidx.annotation.NonNull;
67
import androidx.appcompat.app.AppCompatActivity;
78
import androidx.navigation.NavController;
89
import androidx.navigation.Navigation;
@@ -11,40 +12,53 @@
1112
import androidx.navigation.ui.NavigationUI;
1213

1314
import com.example.one.databinding.ActivityMainBinding;
15+
import com.google.android.material.bottomnavigation.BottomNavigationView;
16+
import com.google.android.material.navigation.NavigationBarView;
17+
import com.google.android.material.transition.MaterialContainerTransform;
1418

15-
public class MainActivity extends AppCompatActivity {
19+
public class MainActivity extends AppCompatActivity { // MainActivity 类继承自 AppCompatActivity
1620

17-
private AppBarConfiguration appBarConfiguration;
18-
private ActivityMainBinding binding;
21+
private AppBarConfiguration appBarConfiguration; // 声明 AppBarConfiguration 类型的变量 appBarConfiguration
22+
private ActivityMainBinding binding; // 声明 ActivityMainBinding 类型的变量 binding
1923

2024
@Override
21-
protected void onCreate(Bundle savedInstanceState) {
22-
super.onCreate(savedInstanceState);
25+
protected void onCreate(Bundle savedInstanceState) { // 重写 onCreate() 方法,这是 Activity 的入口点
26+
super.onCreate(savedInstanceState); // 调用父类的 onCreate() 方法
2327

24-
binding = ActivityMainBinding.inflate(getLayoutInflater());
25-
setContentView(binding.getRoot());
28+
binding = ActivityMainBinding.inflate(getLayoutInflater()); // 使用布局文件生成 binding 实例
29+
setContentView(binding.getRoot()); // 设置 Activity 的内容视图
2630

27-
setSupportActionBar(binding.toolbar);
31+
setSupportActionBar(binding.toolbar); // 将布局文件中的 toolbar 设置为 ActionBar
2832

33+
// 获取 NavHostFragment 实例
2934
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_content_main);
30-
NavController navController = navHostFragment.getNavController();
35+
NavController navController = navHostFragment.getNavController(); // 获取 NavController 实例
3136

37+
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
38+
NavigationUI.setupWithNavController(bottomNavigationView, navController); // 将底部导航栏与 NavController 关联
39+
40+
// 创建 AppBarConfiguration 实例,指定顶部级别的 Fragment
3241
appBarConfiguration = new AppBarConfiguration.Builder(
3342
R.id.FirstFragment, R.id.SecondFragment, R.id.ThirdFragment)
3443
.build();
3544

45+
// 将 ActionBar 与 NavController 关联,并使用 AppBarConfiguration 进行配置
3646
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
47+
48+
3749
}
3850

3951
@Override
40-
public boolean onCreateOptionsMenu(Menu menu) {
41-
getMenuInflater().inflate(R.menu.menu_main, menu);
42-
return true;
52+
public boolean onCreateOptionsMenu(Menu menu) { // 重写 onCreateOptionsMenu() 方法,创建选项菜单
53+
getMenuInflater().inflate(R.menu.menu_main, menu); // 加载菜单资源文件
54+
return true; // 返回 true 表示显示菜单
4355
}
4456

4557
@Override
46-
public boolean onSupportNavigateUp() {
58+
public boolean onSupportNavigateUp() { // 重写 onSupportNavigateUp() 方法,处理向上导航
59+
// 获取 NavController 实例
4760
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
61+
// 使用 NavigationUI 处理向上导航,或者调用父类的 onSupportNavigateUp() 方法
4862
return NavigationUI.navigateUp(navController, appBarConfiguration)
4963
|| super.onSupportNavigateUp();
5064
}

0 commit comments

Comments
 (0)