2014-09-25 81 views
1

我正在爲Android Wear製作自定義錶款。我有一個問題,在仿真器和圓形屏幕設備上沒有正確充氣。我可以在設備上的其他活動中成功加載圓形佈局,但它不適用於錶盤活動本身。Android Wear沒有爲圓形屏幕上的自定義錶盤正確佈局

這是我的清單文件:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.aegiswallet" 
    android:versionCode="1" 
    android:versionName="1.0.0"> 

    <uses-feature android:name="android.hardware.type.watch" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/icon" 
     android:label="@string/app_name" 
     android:theme="@android:style/Theme.DeviceDefault" 
     android:name=".application.AegisWearApplication"> 

     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 

     <activity 
      android:name=".activities.MyActivity" 
      android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <activity 
      android:theme="@android:style/Theme.DeviceDefault.NoActionBar" 
      android:name=".activities.WatchFaceActivity" 
      android:allowEmbedded="true" 
      android:label="Aegis Wallet"> 

      <meta-data 
       android:name="com.google.android.clockwork.home.preview" 
       android:resource="@drawable/watchface" /> 

      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="com.google.android.clockwork.home.category.HOME_BACKGROUND" /> 
      </intent-filter> 
     </activity> 

     <activity android:name=".activities.ReceiveBitcoin" android:label="@string/receive_bitcoin"></activity> 
     <service android:name=".services.MessageListenService"> 
      <intent-filter> 
       <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> 
      </intent-filter> 
     </service> 

    </application> 
</manifest> 

活動「MyActivity」成功膨脹一輪佈局,但「WatchFaceActivity」沒有。 該項目可以在GitHub在這裏找到:https://github.com/bsimic0001/AegisWallet/

下面是每個代碼:

public class MyActivity extends Activity implements SimpleGestureFilter.SimpleGestureListener { 

    private SimpleGestureFilter detector; 
    private TextView mTextView; 
    private TextView balanceView; 

    private static final int SPEECH_REQUEST_CODE = 0; 
    private QRCodeWriter qrCodeWriter; 
    private SharedPreferences prefs; 
    private String address; 
    private ImageView addressImageView; 
    private Context context = this; 

    private int STATE_QR = 100; 
    private int STATE_BAL = 101; 
    private int CURRENT_STATE = 0; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //setContentView(R.layout.activity_my); 
     WatchViewStub stub = new WatchViewStub(this); 

     stub.setRectLayout(R.layout.rect_activity_my); 
     stub.setRoundLayout(R.layout.round_activity_my); 

     detector = new SimpleGestureFilter(this, this); 

     stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { 
      @Override 
      public void onLayoutInflated(WatchViewStub stub) { 

       View rootView = stub.getRootView(); 
       mTextView = (TextView) stub.findViewById(R.id.text); 
       addressImageView = (ImageView) stub.findViewById(R.id.address_image); 
       balanceView = (TextView) stub.findViewById(R.id.balance_text); 

       prefs = PreferenceManager.getDefaultSharedPreferences(context); 
       address = prefs.getString("ADDRESS", null); 

       if (address != null && addressImageView != null) { 

        qrCodeWriter = new QRCodeWriter(); 
        Bitmap addressBitmap = encodeAsBitmap(address, BarcodeFormat.QR_CODE, 200); 
        addressImageView.setImageBitmap(addressBitmap); 

        addressImageView.setVisibility(View.VISIBLE); 
        CURRENT_STATE = STATE_QR; 

       } else { 
        Log.d("MAINACTIVITY", "address image view must be null"); 
       } 

       rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { 
        @Override 
        public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { 

         final boolean round = insets.isRound(); 
         Log.d("MainActivity", "Is the screen round: " + round); 
         return insets; 
        } 
       }); 

      } 
     }); 

     setContentView(stub); 

     //displaySpeechRecognizer(); 
    } 

    // Create an intent that can start the Speech Recognizer activity 
    private void displaySpeechRecognizer() { 
     Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
     intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, 
       RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); 
     // Start the activity, the intent will be populated with the speech text 
     startActivityForResult(intent, SPEECH_REQUEST_CODE); 
    } 

    // This callback is invoked when the Speech Recognizer returns. 
    // This is where you process the intent and extract the speech text from the intent. 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, 
            Intent data) { 
     if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) { 
      List<String> results = data.getStringArrayListExtra(
        RecognizerIntent.EXTRA_RESULTS); 
      String spokenText = results.get(0); 

      Log.d("Main", "spoken text: " + spokenText); 
     } 
     super.onActivityResult(requestCode, resultCode, data); 
    } 

    public Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int dimension) { 

     Bitmap bitmap = null; 

     try { 
      final Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); 
      hints.put(EncodeHintType.MARGIN, 1); 
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); 
      final BitMatrix result = qrCodeWriter.encode(contents, BarcodeFormat.QR_CODE, dimension, dimension, hints); 

      final int width = result.getWidth(); 
      final int height = result.getHeight(); 
      final int[] pixels = new int[width * height]; 

      for (int y = 0; y < height; y++) { 
       final int offset = y * width; 
       for (int x = 0; x < width; x++) { 
        pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE; 
       } 
      } 

      bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
      bitmap.setPixels(pixels, 0, width, 0, 0, width, height); 
      return bitmap; 

     } catch (WriterException e) { 
      Log.e("Basic Utils", "cannot write to bitmap " + e.getMessage()); 
     } 
     return bitmap; 
    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent me) { 
     // Call onTouchEvent of SimpleGestureFilter class 
     this.detector.onTouchEvent(me); 
     return super.dispatchTouchEvent(me); 
    } 

    @Override 
    public void onSwipe(int direction) { 
     String str = ""; 

     switch (direction) { 

      case SimpleGestureFilter.SWIPE_RIGHT: 
       str = "Swipe Right"; 
       break; 
      case SimpleGestureFilter.SWIPE_LEFT: 
       str = "Swipe Left"; 
       break; 
      case SimpleGestureFilter.SWIPE_DOWN: 
       str = "Swipe Down"; 
       handleSwipe(SimpleGestureFilter.SWIPE_DOWN); 
       break; 
      case SimpleGestureFilter.SWIPE_UP: 
       str = "Swipe Up"; 
       handleSwipe(SimpleGestureFilter.SWIPE_UP); 
       break; 

     } 
    } 

    @Override 
    public void onDoubleTap() { 
     Log.d("MyActivity", "Double Tap"); 
    } 

    private void handleSwipe(int swipeType){ 

     if(CURRENT_STATE == STATE_QR){ 
      addressImageView.setVisibility(View.GONE); 
      balanceView.setVisibility(View.VISIBLE); 
      CURRENT_STATE = STATE_BAL; 

      balanceView.setText("WALLET BALANCE:\n" + prefs.getString("BALANCE", "Balance not Synced")); 
     } 
     else if(CURRENT_STATE == STATE_BAL){ 
      addressImageView.setVisibility(View.VISIBLE); 
      balanceView.setVisibility(View.GONE); 
      CURRENT_STATE = STATE_QR; 
     } 


    } 
} 

public class WatchFaceActivity extends Activity { 

    private final static IntentFilter intentFilter; 
    private boolean isDimmed = false; 

    private String TAG = "AegisWearWatchFace"; 

    private Handler mHandler; 

    TextView time; 
    TextView timeAmPm; 
    TextView btcValue; 
    TextView walletBalance; 

    SharedPreferences prefs; 

    static { 
     intentFilter = new IntentFilter(); 
     intentFilter.addAction(Intent.ACTION_TIME_TICK); 
     intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 
     intentFilter.addAction(Intent.ACTION_TIME_CHANGED); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     Log.d(TAG, "inside the watch face activity"); 
     WatchViewStub stub = new WatchViewStub(this); 
     stub.setRectLayout(R.layout.rect_activity_watch_face); 
     stub.setRoundLayout(R.layout.round_activity_watch_face); 

     stub.requestApplyInsets(); 


     stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { 
      @Override 
      public void onLayoutInflated(WatchViewStub stub) { 

       Log.d(TAG, "Layout is inflated!"); 

       time = (TextView) stub.findViewById(R.id.time); 
       timeAmPm = (TextView) stub.findViewById(R.id.time_ampm); 
       btcValue = (TextView) stub.findViewById(R.id.bitcoin_value); 
       walletBalance = (TextView) stub.findViewById(R.id.wallet_balance); 

       View rootView = stub.getRootView(); 

       rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { 
        @Override 
        public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { 
         final boolean round = insets.isRound(); 
         Log.d("WatchFaceActivity", "Is the screen round: " + round); 
         return insets; 
        } 
       }); 

      } 
     }); 



     setContentView(stub); 

     prefs = PreferenceManager.getDefaultSharedPreferences(this); 

     timeInfoReceiver.onReceive(this, registerReceiver(null, intentFilter)); 
     registerReceiver(timeInfoReceiver, intentFilter); 
    } 

    public BroadcastReceiver timeInfoReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context arg0, Intent intent) { 
      Log.v("WatchFace", "timeChanged();"); 
      updateLayout(); 
     } 
    }; 


    @Override 
    protected void onPause() { 
     super.onPause(); 
     isDimmed = true; 
     Log.d(TAG, "dimmed"); 
     updateLayout(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     isDimmed = false; 
     Log.d(TAG, "not dimmed"); 
     updateLayout(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unregisterReceiver(timeInfoReceiver); 
    } 

    public void updateLayout() { 

     Calendar calendar = Calendar.getInstance(); 

     int hour = calendar.get(Calendar.HOUR); 
     int minute = calendar.get(Calendar.MINUTE); 
     String am_pm; 

     if(calendar.get(Calendar.AM_PM) == 0) am_pm = "AM"; else am_pm = "PM"; 

     String btcValueString = prefs.getString("BTCAMOUNT", ""); 

     String hourText = hour + ""; 

     if(hour == 0) 
      hour = 12; 

     if(hour < 10) 
      hourText = "0" + hourText; 

     String minuteText = minute + ""; 
     if(minute < 10) 
      minuteText = "0" + minuteText; 

     if(time != null) { 
      time.setText(hourText + ":" + minuteText); 
      timeAmPm.setText(am_pm); 
      btcValue.setText(btcValueString); 
      walletBalance.setText(prefs.getString("BALANCE", "")); 
     } 
     else { 
      Log.d("WatchFace", "time is null for some reason..."); 
     } 

    } 
} 

回答

1

嘗試設置你的onApplyWindowInsets內stub.onApplyWindowInsets(插圖)()方法。

+0

試過這種沒有工作。 – bsimic 2014-10-30 14:47:40

0

在新的andrioid smartwatch SDK發佈之前,您無法在自定義錶盤上使用setOnApplyWindowInsetsListener/onApplyWindowInsets。此功能僅適用於智能手錶應用程序。

要知道,如果鐘面是圓的,你可以使用:

public static boolean heightSameAsWidth(Context context) { 
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
    Display display = wm.getDefaultDisplay(); 

    DisplayMetrics metrics = new DisplayMetrics(); 
    display.getMetrics(metrics); 

    int width = metrics.widthPixels; 
    int height = metrics.heightPixels; 

    return height == width; 
} 

private void checkIfWatchIsRound() { 
    if (heightSameAsWidth(getApplicationContext())) { 
     isRound = false; 
    } else { 
     isRound = true; 
    } 
}