Android单文件项目拆分重构求助:CoreActivity代码优化
Hey there! I see you're looking to split up that monolithic CoreActivity into cleaner, more maintainable components. Let's break this down by separating each distinct feature into its own dedicated class, which will make your code easier to read, test, and update.
Step 1: Identify Feature Modules
First, let's map out the key responsibilities in your original code:
- WebView initialization, configuration, and navigation
- Search bar input handling and keyboard management
- Swipe gesture logic for navigation and WebView resizing
- Toolbar/preference panel animation and visibility control
We'll create a helper class for each of these, then wire them up in a simplified CoreActivity.
Step 2: Create Helper Classes
1. WebViewSetupHelper (Handles WebView Configuration)
This class encapsulates all WebView setup logic, so you don't clutter your activity with settings.
import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; public class WebViewSetupHelper { private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3"; private final WebView webView; public WebViewSetupHelper(WebView webView) { this.webView = webView; } public void setupWebView(String defaultUrl) { WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setSupportZoom(true); webSettings.setLoadWithOverviewMode(true); webSettings.setUseWideViewPort(true); webSettings.setUserAgentString(DEFAULT_USER_AGENT); webView.setWebViewClient(new WebViewClient()); webView.loadUrl(defaultUrl); } public void loadUrl(String url) { webView.loadUrl(url); } public boolean canGoBack() { return webView.canGoBack(); } public void goBack() { webView.goBack(); } public boolean canGoForward() { return webView.canGoForward(); } public void goForward() { webView.goForward(); } public void reload() { webView.reload(); } }
2. SearchBarHandler (Manages Search Input)
This class handles the search bar's editor action, URL validation, and keyboard hiding logic.
import android.content.Context; import android.view.KeyEvent; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.TextView; public class SearchBarHandler implements TextView.OnEditorActionListener { private final EditText searchEditText; private final Context context; private final WebViewSetupHelper webViewHelper; public SearchBarHandler(EditText searchEditText, Context context, WebViewSetupHelper webViewHelper) { this.searchEditText = searchEditText; this.context = context; this.webViewHelper = webViewHelper; searchEditText.setOnEditorActionListener(this); } @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH) { String input = searchEditText.getText().toString().trim(); if (!input.isEmpty()) { String targetUrl = buildTargetUrl(input); webViewHelper.loadUrl(targetUrl); hideKeyboard(); searchEditText.clearFocus(); } return true; } return false; } private String buildTargetUrl(String input) { // Check if input is a valid domain if (input.contains(".com") || input.contains(".ca") || input.contains(".net") || input.contains(".org")) { return "https://www." + input; } // Otherwise, treat as search query return "https://www.google.ca/search?q=" + input; } private void hideKeyboard() { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(searchEditText.getWindowToken(), 0); } }
3. SwipeGestureHandler (Handles Swipe Logic)
This class wraps the Swipe library logic, keeping gesture code out of your activity.
import android.os.Handler; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.webkit.WebView; import com.github.pwittchen.swipe.library.rx2.Swipe; import com.github.pwittchen.swipe.library.rx2.SwipeListener; public class SwipeGestureHandler implements SwipeListener { private final Swipe swipe; private final WebView webView; private final WebViewSetupHelper webViewHelper; private final View toolbar; private final View preferenceToolbar; private final int animDelay = 350; private int webViewState = 0; // 0 = normal, 1 = enlarged public SwipeGestureHandler(WebView webView, WebViewSetupHelper webViewHelper, View toolbar, View preferenceToolbar) { this.webView = webView; this.webViewHelper = webViewHelper; this.toolbar = toolbar; this.preferenceToolbar = preferenceToolbar; this.swipe = new Swipe(350, 700); this.swipe.setListener(this); } public void dispatchTouchEvent(MotionEvent event) { swipe.dispatchTouchEvent(event); } @Override public void onSwipingLeft(MotionEvent event) { if (webViewHelper.canGoForward()) { webViewHelper.goForward(); } else { webViewHelper.reload(); } } @Override public void onSwipedLeft(MotionEvent event) {} @Override public void onSwipingRight(MotionEvent event) { if (webViewHelper.canGoBack()) { webViewHelper.goBack(); } else { webViewHelper.reload(); } } @Override public void onSwipedRight(MotionEvent event) {} @Override public void onSwipingUp(MotionEvent event) {} @Override public void onSwipedUp(MotionEvent event) { if (webViewState == 0) { Animation enlargeAnim = AnimationUtils.loadAnimation(webView.getContext(), R.anim.m_webview_enlarge); webView.startAnimation(enlargeAnim); webViewState = 1; new Handler().postDelayed(() -> toolbar.setVisibility(View.GONE), animDelay); } } @Override public void onSwipingDown(MotionEvent event) {} @Override public void onSwipedDown(MotionEvent event) { if (webViewState == 1) { Animation shrinkAnim = AnimationUtils.loadAnimation(webView.getContext(), R.anim.m_webview_shrink); webView.startAnimation(shrinkAnim); preferenceToolbar.setVisibility(View.GONE); webViewState = 0; new Handler().postDelayed(() -> toolbar.setVisibility(View.VISIBLE), animDelay); } } }
4. ToolbarInteractionHandler (Manages Toolbar Animations)
This class handles the preference panel touch event and toolbar animations.
import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.support.constraint.ConstraintLayout; public class ToolbarInteractionHandler implements View.OnTouchListener { private final ConstraintLayout toolbar; private final ConstraintLayout preferences; private final ConstraintLayout preferenceToolbar; private int x = 0; public ToolbarInteractionHandler(ConstraintLayout toolbar, ConstraintLayout preferences, ConstraintLayout preferenceToolbar) { this.toolbar = toolbar; this.preferences = preferences; this.preferenceToolbar = preferenceToolbar; preferences.setOnTouchListener(this); } @Override public boolean onTouch(View view, MotionEvent motionEvent) { preferences.setVisibility(View.GONE); x = 1; Animation toolbarGoneAnim = AnimationUtils.loadAnimation(toolbar.getContext(), R.anim.m_toolbar_gone); toolbar.startAnimation(toolbarGoneAnim); if (preferences.getVisibility() == View.GONE || x == 1) { Animation prefToolbarAppearAnim = AnimationUtils.loadAnimation(toolbar.getContext(), R.anim.m_preference_toolbar_appear); preferenceToolbar.startAnimation(prefToolbarAppearAnim); } return false; } }
Step 3: Simplified CoreActivity.java
Now, your main activity will just initialize the views and wire up all the helper classes—no more messy nested listeners or configuration code!
import android.os.Bundle; import android.support.constraint.ConstraintLayout; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.webkit.WebView; import android.widget.EditText; import com.github.pwittchen.gesture.library.Gesture; import com.github.pwittchen.gesture.library.GestureListener; public class CoreActivity extends AppCompatActivity { // Constants private static final String DEFAULT_URL = "https://www.Google.ca"; // Views private ConstraintLayout mToolbar; private ConstraintLayout mPreferences; private ConstraintLayout mPreferenceToolbar; private EditText mWebViewSearch; private WebView mWebView; // Helper Classes private WebViewSetupHelper webViewSetupHelper; private SearchBarHandler searchBarHandler; private SwipeGestureHandler swipeGestureHandler; private ToolbarInteractionHandler toolbarInteractionHandler; private Gesture webGesture; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_core); // Initialize Views initViews(); // Setup Helpers setupHelpers(); } private void initViews() { mToolbar = findViewById(R.id.m_Toolbar); mPreferences = findViewById(R.id.m_Preferences); mWebViewSearch = findViewById(R.id.m_WebView_Search); mWebView = findViewById(R.id.m_WebView); mPreferenceToolbar = findViewById(R.id.m_Preferences_Toolbar); mPreferenceToolbar.setVisibility(View.GONE); } private void setupHelpers() { // WebView Setup webViewSetupHelper = new WebViewSetupHelper(mWebView); webViewSetupHelper.setupWebView(DEFAULT_URL); // Search Bar Handler searchBarHandler = new SearchBarHandler(mWebViewSearch, this, webViewSetupHelper); // Swipe Gesture Handler swipeGestureHandler = new SwipeGestureHandler(mWebView, webViewSetupHelper, mToolbar, mPreferenceToolbar); // Toolbar Interaction Handler toolbarInteractionHandler = new ToolbarInteractionHandler(mToolbar, mPreferences, mPreferenceToolbar); // Gesture Library (kept as-is since it's mostly empty for now) setupWebGesture(); } private void setupWebGesture() { webGesture = new Gesture(); webGesture.addListener(new GestureListener() { @Override public void onPress(MotionEvent motionEvent) {} @Override public void onTap(MotionEvent motionEvent) {} @Override public void onDrag(MotionEvent motionEvent) {} @Override public void onMove(MotionEvent motionEvent) {} @Override public void onRelease(MotionEvent motionEvent) {} @Override public void onLongPress(MotionEvent motionEvent) {} @Override public void onMultiTap(MotionEvent motionEvent, int clicks) {} }); } @Override public boolean dispatchTouchEvent(MotionEvent event) { swipeGestureHandler.dispatchTouchEvent(event); webGesture.dispatchTouchEvent(event); return super.dispatchTouchEvent(event); } }
Key Benefits of This Refactoring
- Single Responsibility Principle: Each helper class does one job (e.g.,
SearchBarHandleronly handles search input) - Improved Readability: CoreActivity is now just a coordinator, not a dumping ground for all logic
- Easier Maintenance: If you need to tweak WebView settings or swipe logic, you only edit one file
- Reusability: You can reuse these helper classes in other activities if needed
Quick Notes for Future Improvements
- Consider using WeakReference in helper classes that hold Context/View references to avoid memory leaks
- Extract string constants (like URLs, animation IDs) to
strings.xmlfor better localization - Add null checks for views to prevent crashes if a view isn't found
内容的提问来源于stack exchange,提问作者EquiWare

