我几周前开始使用Android编码,在此之前我从未使用oop(我有一些c背景和微控制器嵌入c等),因此我可能会认为这个想法完全错误,但是我需要帮助才能继续:
我创建了一个示例活动,用作一个完美符合我意图的UI。之后我想用它作为未来设计的定制化合物,所以我试图做出改变,但无法弄清楚。该化合物有3个textviews和2个按钮。我还实现了在按钮旁边使用的手势(所以我可以向上或向下滚动来改变值)。
现在当我使用这个自定义化合物时,我收到一个错误。我无法理解为什么。
这里是我的复合布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/CustomTouchPickerLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".CustomTouchPickerActivity" >
<TextView
android:id="@+id/textViewMid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewTop"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:onClick="onClickMid"
android:paddingBottom="20sp"
android:paddingTop="20sp"
android:textSize="45sp"
android:text="Mid"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/textViewBot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewMid"
android:textSize="22sp"
android:text="Bot"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/textViewTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textViewBot"
android:layout_marginTop="52dp"
android:textSize="22sp"
android:text="Top"
android:layout_centerHorizontal="true"/>
<Button
android:id="@+id/buttonTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="OnClickButtonTop"
android:text="Up"
android:layout_centerHorizontal="true"/>
<Button
android:id="@+id/buttonBot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewBot"
android:layout_centerHorizontal="true"
android:onClick="OnClickButtonBot"
android:text="Down" />
这是我的化合物的.java文件:
package com.vestel.customtouchpicker;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CustomTouchPicker extends RelativeLayout {
public int count_sag=0;
public int count_sol=0;
public int count_button_sol=0;
public int count_button_sag=0;
private GestureDetector gestureDetector;
public CustomTouchPicker(Context context, AttributeSet attrs) {
super(context,attrs);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.activity_custom_touch_picker,this);
gestureDetector = new GestureDetector(new SwipeGestureDetector());
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
TextView textViewMid = (TextView)findViewById(R.id.textViewMid);
Button buttonTop = (Button) findViewById(R.id.buttonTop);
Button buttonBot = (Button) findViewById(R.id.buttonBot);
textViewTop.setVisibility(View.INVISIBLE);
textViewBot.setVisibility(View.INVISIBLE);
buttonTop.setVisibility(Button.INVISIBLE);
buttonBot.setVisibility(Button.INVISIBLE);
textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
}
private class SwipeGestureDetector extends SimpleOnGestureListener {
// Swipe properties, you can change it to make the swipe
// longer or shorter and speed
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 200;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
public boolean onScroll(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
float diffAbs = Math.abs(e1.getY() - e2.getY());
float diff = e1.getX() - e2.getX();
float diff_y = e1.getY() - e2.getY();
float diffAbs_x = Math.abs(e1.getX() - e2.getY());
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
// down swipe
if(textViewTop.getVisibility()==0){
if (e1.getY()>e2.getY()) {
if(diff_y>20)
{
count_button_sol=count_button_sol+1;
}
CustomTouchPicker.this.onDownSwipe();
}
// up swipe
else if (e1.getY()<e2.getY())
{
if(-diff_y>20){
count_button_sol=count_button_sol+1;
}
CustomTouchPicker.this.onUpSwipe();
}
}
}catch (Exception e) {
Log.e("YourActivity", "Error on gestures");
}
return false;
}
}
public void onClickMid(View view)
{
count_sol=count_sol+1;
if(count_sol%2==1){
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
Button buttonTop = (Button) findViewById(R.id.buttonTop);
Button buttonBot = (Button) findViewById(R.id.buttonBot);
textViewTop.setVisibility(View.VISIBLE);
textViewBot.setVisibility(View.VISIBLE);
buttonTop.setVisibility(Button.VISIBLE);
buttonBot.setVisibility(Button.VISIBLE);
textViewBot.setAlpha(0.2f);
textViewTop.setAlpha(0.2f);
}
else
{
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
Button buttonTop = (Button) findViewById(R.id.buttonTop);
Button buttonBot = (Button) findViewById(R.id.buttonBot);
textViewTop.setVisibility(View.INVISIBLE);
textViewBot.setVisibility(View.INVISIBLE);
buttonTop.setVisibility(Button.INVISIBLE);
buttonBot.setVisibility(Button.INVISIBLE);
}
}
public void OnClickButtonTop (View view){
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
TextView textViewMid = (TextView)findViewById(R.id.textViewMid);
switch (count_button_sol%4)
{
case 0: textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
case 1: textViewTop.setText("4°");
textViewMid.setText("6°");
textViewBot.setText("8°");
break;
case 2: textViewTop.setText("6°");
textViewMid.setText("8°");
textViewBot.setText("2°");
break;
case 3: textViewTop.setText("8°");
textViewMid.setText("2°");
textViewBot.setText("4°");
break;
default:textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
}
count_button_sol=count_button_sol+1;
}
public void OnClickButtonBot (View view){
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
TextView textViewMid = (TextView)findViewById(R.id.textViewMid);
switch (count_button_sol%4)
{
case 3: textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
case 2: textViewTop.setText("4°");
textViewMid.setText("6°");
textViewBot.setText("8°");
break;
case 1: textViewTop.setText("6°");
textViewMid.setText("8°");
textViewBot.setText("2°");
break;
case 0: textViewTop.setText("8°");
textViewMid.setText("2°");
textViewBot.setText("4°");
break;
default:textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
}
count_button_sol=count_button_sol+1;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
{
return true;
}
return super.onTouchEvent(event);
}
private void onDownSwipe()
{
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
TextView textViewMid = (TextView)findViewById(R.id.textViewMid);
switch (count_button_sol%4){
case 0: textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
case 1: textViewTop.setText("4°");
textViewMid.setText("6°");
textViewBot.setText("8°");
break;
case 2: textViewTop.setText("6°");
textViewMid.setText("8°");
textViewBot.setText("2°");
break;
case 3: textViewTop.setText("8°");
textViewMid.setText("2°");
textViewBot.setText("4°");
break;
default:textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
}
}
private void onUpSwipe() {
TextView textViewTop = (TextView)findViewById(R.id.textViewTop);
// textViewTop.setAlpha(0.5f);
TextView textViewBot = (TextView)findViewById(R.id.textViewBot);
TextView textViewMid = (TextView)findViewById(R.id.textViewMid);
// textViewBot.setAlpha(0.5f);
switch (count_button_sol%4){
case 3: textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
case 2: textViewTop.setText("4°");
textViewMid.setText("6°");
textViewBot.setText("8°");
break;
case 1: textViewTop.setText("6°");
textViewMid.setText("8°");
textViewBot.setText("2°");
break;
case 0: textViewTop.setText("8°");
textViewMid.setText("2°");
textViewBot.setText("4°");
break;
default:textViewTop.setText("2°");
textViewMid.setText("4°");
textViewBot.setText("6°");
break;
}
}
}
这是我测试的主要活动布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.vestel.customtouchpicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
这里是MainActivity.java
package com.vestel.customtouchpicker;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
和android清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vestel.customtouchpicker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.vestel.customtouchpicker.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
最后是我的logcat
04-04 14:41:59.049: E/Trace(31339): error opening trace file: No such file or directory (2)
04-04 14:41:59.319: E/AndroidRuntime(31339): FATAL EXCEPTION: main
04-04 14:41:59.319: E/AndroidRuntime(31339): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.vestel.customtouchpicker/com.vestel.customtouchpicker.MainActivity}: android.view.InflateException: Binary XML file line #12: Error inflating class com.vestel.customtouchpicker
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2351)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.ActivityThread.access$600(ActivityThread.java:151)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.os.Handler.dispatchMessage(Handler.java:99)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.os.Looper.loop(Looper.java:155)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.ActivityThread.main(ActivityThread.java:5454)
04-04 14:41:59.319: E/AndroidRuntime(31339): at java.lang.reflect.Method.invokeNative(Native Method)
04-04 14:41:59.319: E/AndroidRuntime(31339): at java.lang.reflect.Method.invoke(Method.java:511)
04-04 14:41:59.319: E/AndroidRuntime(31339): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
04-04 14:41:59.319: E/AndroidRuntime(31339): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
04-04 14:41:59.319: E/AndroidRuntime(31339): at dalvik.system.NativeStart.main(Native Method)
04-04 14:41:59.319: E/AndroidRuntime(31339): Caused by: android.view.InflateException: Binary XML file line #12: Error inflating class com.vestel.customtouchpicker
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:698)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
04-04 14:41:59.319: E/AndroidRuntime(31339): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:363)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.Activity.setContentView(Activity.java:1912)
04-04 14:41:59.319: E/AndroidRuntime(31339): at com.vestel.customtouchpicker.MainActivity.onCreate(MainActivity.java:12)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.Activity.performCreate(Activity.java:5066)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307)
04-04 14:41:59.319: E/AndroidRuntime(31339): ... 11 more
04-04 14:41:59.319: E/AndroidRuntime(31339): Caused by: java.lang.ClassNotFoundException: com.vestel.customtouchpicker
04-04 14:41:59.319: E/AndroidRuntime(31339): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
04-04 14:41:59.319: E/AndroidRuntime(31339): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
04-04 14:41:59.319: E/AndroidRuntime(31339): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.createView(LayoutInflater.java:552)
04-04 14:41:59.319: E/AndroidRuntime(31339): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
04-04 14:41:59.319: E/AndroidRuntime(31339): ... 21 more
顺便说一句,如果你直接使用代码作为活动它可以工作(当然我删除了一些像“setContentView”等等的行
答案 0 :(得分:0)
您在主要活动布局中缺少您的班级名称。它无法找到类com.vestel.customtouchpicker
,这只是自定义组件的包名而不是类名。在主要活动布局中将完全限定名称设为com.vestel.customtouchpicker.CustomTouchPicker
,它应该有效。
更改为:
<com.vestel.customtouchpicker.CustomTouchPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
编辑:这是ClassNotFoundException的答案,我没有检查你的所有代码。所以可能还有另一个问题。
答案 1 :(得分:0)
我猜这个错误是由以下两行引起的:
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.activity_custom_touch_picker,this);
因为context.getSystemService中的“context”可能会引发异常。 可能你可以使用
context.getApplicationContext().getSystemService
因为您试图使用活动之外的上下文