我创建了3个类似于快照聊天应用程序的选项卡 . 我的主要活动如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.crowderia.chat.MainActivity"
android:background="@android:color/transparent">
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"/>
<View
android:id="@+id/am_background_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha=".5"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.crowderia.chat.view.SnapTabView
android:id="@+id/am_snap_tabs"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginBottom="16dp"/>
</RelativeLayout>
在我的view_snap_tabs.xml文件中,如下所示,但当我将此作为视图包含在activity_main.xml文件中时显示
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="184dp"
tools:layout_gravity="bottom"
tools:background="@color/light_purple"
android:id="@+id/snaps">
<ImageView
android:id="@+id/vst_center_image"
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_gravity="center|bottom"
android:src="@drawable/large_circle"
android:layout_marginBottom="96dp"/>
<ImageView
android:id="@+id/vst_start_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginBottom="56dp"
android:layout_marginStart="24dp"
android:layout_gravity="start|bottom"
android:src="@drawable/ic_chat_bubble_24dp"/>
<ImageView
android:id="@+id/vst_end_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginBottom="56dp"
android:layout_marginEnd="24dp"
android:layout_gravity="end|bottom"
android:src="@drawable/ic_group_work_24dp"/>
<ImageView
android:id="@+id/vst_bottom_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginBottom="48dp"
android:layout_gravity="center|bottom"
android:src="@drawable/small_circle"/>
<View
android:id="@+id/vst_indicator"
android:layout_width="48dp"
android:layout_height="4dp"
android:layout_gravity="bottom|center"
android:layout_marginBottom="44dp"
android:background="@drawable/indicator_background"/>
</FrameLayout>
and I have created a class for control the view_snap_tabs.xml becasuse I want to make changes it slide throw each fragment
在我的MainActivity.java类中,我有如下所示的包含
SnapTabView snapTabView = (SnapTabView) findViewById(R.id.am_snap_tabs);
snapTabView.setUpWithViewPager(viewPager);
和我的SnapTabView.java类如下
public class SnapTabView extends FrameLayout implements ViewPager.OnPageChangeListener {
private ImageView mCenterImage;
private ImageView mStartImage;
private ImageView mBottomImage;
private ImageView mEndImage;
private View mIndicator;
private ArgbEvaluator mArgbEvaluator;
private int mCenterColor;
private int mSideColor;
private int mEndViewsTranslationX;
private int mIndicatorTranslationX;
private int mCenterTransationY;
public SnapTabView(@NonNull Context context) {
this(context, null);
}
public SnapTabView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SnapTabView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
LayoutInflater.from(getContext()).inflate(R.layout.view_snap_tabs, this, false);
mCenterImage = (ImageView) findViewById(R.id.vst_center_image);
mBottomImage = (ImageView) findViewById(R.id.vst_bottom_image);
mEndImage = (ImageView) findViewById(R.id.vst_end_image);
mStartImage = (ImageView) findViewById(R.id.vst_start_image);
mIndicator = (View) findViewById(R.id.vst_indicator);
mCenterColor = ContextCompat.getColor(getContext(), R.color.white);
mSideColor = ContextCompat.getColor(getContext(), R.color.dark_grey);
mArgbEvaluator = new ArgbEvaluator();
mIndicatorTranslationX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics());
mBottomImage.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mEndViewsTranslationX = (int) ((mBottomImage.getX() - mStartImage.getX()) - mIndicatorTranslationX);
mBottomImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
mCenterTransationY = getHeight() - mBottomImage.getBottom();
}
});
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 0) {
setColor(1 - positionOffset);
moveViews(1 - positionOffset);
mIndicator.setTranslationX((positionOffset - 1) * mIndicatorTranslationX);
moveAndScaleCenter(1 - positionOffset);
} else if(position == 1) {
setColor(positionOffset);
moveViews(positionOffset);
mIndicator.setTranslationX(positionOffset * mIndicatorTranslationX);
moveAndScaleCenter(positionOffset);
}
}
public void setUpWithViewPager(final ViewPager viewPager) {
viewPager.addOnPageChangeListener(this);
mStartImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if(viewPager.getCurrentItem() != 0)
viewPager.setCurrentItem(0);
}
});
mEndImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if(viewPager.getCurrentItem() != 2)
viewPager.setCurrentItem(2);
}
});
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
private void setColor(float fractionFromCenter) {
int color = (int) mArgbEvaluator.evaluate(fractionFromCenter, mCenterColor, mSideColor);
mCenterImage.setColorFilter(color);
mStartImage.setColorFilter(color);
mEndImage.setColorFilter(color);
}
private void moveViews(float fractionFromCenter) {
mStartImage.setTranslationX(fractionFromCenter * mEndViewsTranslationX);
mEndImage.setTranslationX(-fractionFromCenter * mEndViewsTranslationX);
mIndicator.setAlpha(fractionFromCenter);
mIndicator.setScaleX(fractionFromCenter);
}
private void moveAndScaleCenter(float fractionFromCenter) {
float scale = .7f + ((1 - fractionFromCenter) * .3f);
mCenterImage.setScaleX(scale);
mCenterImage.setScaleY(scale);
int translation = (int) (fractionFromCenter * mCenterTransationY);
mCenterImage.setTranslationY(translation);
mBottomImage.setTranslationY(translation);
mBottomImage.setAlpha(1 - fractionFromCenter);
}
}
为什么viewsnaptabs没有显示在activity_main.xml文件中
如果我运行我得到如下的错误
FATAL EXCEPTION:main进程:com.example.crowderia.chat,PID:13383 java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.crowderia.chat/com.example.crowderia.chat.MainActivity}:android .view.InflateException:二进制XML文件行#0:在android.app.ActivityThread.handleLaunchActivity(在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2594)处输入类com.example.crowderia.chat.view.SnapTabView时出错 . ActivityThread.java:2685)在Android.app.Handler.dispatchMessage(处理程序 . )的android.app.ActivityThread.access $ 900(ActivityThread.java:188)android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1530) . java:111)在android.app.Looper.loop(Looper.java:210)的android.app.ActivityThread.main(ActivityThread.java:5839)java.lang.reflect.Method.invoke(Native Method)at java com.android.internal.os.Zygo的com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1113)中的.lang.reflect.Method.invoke(Method.java:372) teInit.main(ZygoteInit.java:879)引起:android.view.InflateException:二进制XML文件行#0:在android.view.LayoutInflater.createView(LayoutInflater)中输出类com.example.crowderia.chat.view.SnapTabView时出错.java:633)在Android.view.LayoutInflater.inflate(LayoutInflater.java:504)的android.view.LayoutInflater.rInflate(LayoutInflater.java:806)的android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)在Android.view.LayoutInflater.inflate(LayoutInflater.java:414)的android.view.LayoutInflater.inflate(LayoutInflater.java:365)在android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)at at在android.app.Activity.performCreate(Activity.java:)的com.example.crowderia.chat.MainActivity.onCreate(MainActivity.java:26)上的android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139): 6177)在Android.app.ActivityThread.performLa的android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)在android.app.ActivityThread.access上的android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2685)的unchActivity(ActivityThread.java:2541)$ 900(ActivityThread.java:188)在android.app.ActivityThread $ H.handleMessage( ActivityThread.java:1530)android.app.Handler.dispatchMessage(Handler.java:111)android.app.Looper.loop(Looper.java:210)android.app.ActivityThread.main(ActivityThread.java:5839) )at java.lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java) :1113)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)由java.lang上的java.lang.reflect.Constructor.newInstance(Native Method)引起的java.lang.reflect.InvocationTargetException .reflect.Constructor.newInstance(Constructor.java:288)在android.view.LayoutInflater.createView(LayoutInflater.java:607)android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)android.vi在android.view.LayoutInflater.inflate的android.view.LayoutInflater.inflate(LayoutInflater.java:414)的android.view.LayoutInflater.inflate(LayoutInflater.java:504)中的ew.LayoutInflater.rInflate(LayoutInflater.java:806) (LayoutInflater.java:365)位于android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287),位于com.example的android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139) . android.app.ActivityThread上android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)的android.app.Activity.performCreate(Activity.java:6177)上的crowderia.chat.MainActivity.onCreate(MainActivity.java:26) Android.app.ActivityThread $ 6.handleMessage上的android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2685)上的.performLaunchActivity(ActivityThread.java:2541),android.app.ActivityThread.access $ 900(ActivityThread.java:188) (ActivityThread.java:1530)在android.os.Handler.dispatchMessage(Handler.java:111)的android.app.Looper.loop(Looper.java:210)在android.app.ActivityThread.main(ActivityThread.java:5839)的java.lang上 . 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1113)的com.android.internal.os.ZygoteInit上的java.lang.reflect.Method.invoke(Method.java:372)中的reflect.Method.invoke(Native Method) . android.internal.os.ZygoteInit.main(ZygoteInit.java:879)引起:java.lang.NullPointerException:尝试在空对象上调用虚方法'android.view.ViewTreeObserver android.widget.ImageView.getViewTreeObserver()'参考com.example.crowderia.chat.view.SnapTabView.init(SnapTabView.java:58)com.example.crowderia.chat.view.SnapTabView . (SnapTabView.java:45)com.example.crowderia.chat .view.SnapTabView . (SnapTabView.java:0)位于android.view.LayoutInflater的java.lang.reflect.Constructor.newInstance(Native Method)中的java.lang.reflect.Constructor.newInstance(Constructor.java:288) . createView(LayoutInflater.java:607)at a位于android.view.LayoutInflater的android.view.LayoutInflater.inflate(LayoutInflater.java:504)的android.view.LayoutInflater.rInflate(LayoutInflater.java:806)中的ndroid.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743) .inflate(LayoutInflater.java:414)位于android.sview.LayoutInflater.inflate(LayoutInflater.java:365),位于android.support.v7的android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287) . app.AppCompatActivity.setContentView(AppCompatActivity.java:139)位于android.app的android.app.Activity.performCreate(Activity.java:6177)的com.example.crowderia.chat.MainActivity.onCreate(MainActivity.java:26) .Instrumentation.callActivityOnCreate(Instrumentation.java:1112)在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2541)的android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2685)android.app.ActivityThread.access $ 900 (ActivityThread.java:188)在android.app.ActivityThread $ H.handleMessage(ActivityT) hread.java:1530)android.app.Handler.dispatchMessage(Handler.java:111)android.app.Looper.loop(Looper.java:210)android.app.ActivityThread.main(ActivityThread.java:5839) )at java.lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java) :1113)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)
1 回答
我猜你必须把
init();
也放在另外两个构造函数中 . 这可能无法解决这个问题,但这是一个开始 .你还必须添加如下视图:
这是一个关于custom views的热门问题