You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android单文件项目拆分重构求助:CoreActivity代码优化

Refactoring Your CoreActivity into Modular Components

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., SearchBarHandler only 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.xml for better localization
  • Add null checks for views to prevent crashes if a view isn't found

内容的提问来源于stack exchange,提问作者EquiWare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:22