导航:首页 > 操作系统 > android复制view

android复制view

发布时间:2022-09-28 14:58:21

① 怎样在android Menu item中使用自定义View

1.自定义属性:attrs.xml

2.MenuItemView.java源码

package com.dandy.widget;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import com.lingyun.switchbutton.R;

/**
* 设置,菜单中的布局项
* 默认控件是纵向居中显示,所有paddingTop和paddingBottom在这没有作用
* Created by dandy on 2016/4/14.
*/
public class MenuItemView extends View{

private static final String TAG = "MenuItemView";

/**默认是按下状态的最小值**/
private static final long PRESSED_TIMEOUT = 10;

/**默认控件距离边界的大小**/
private static final int PADDING_DEFAULT = 18;

/**默认控件的高**/
private static final int HEIGHT_DEFAULT = 50;

/**文字绘制时默认大小**/
private static final int TEXTSZIE_DEFAULT = 14;

/**尾部箭头图标大小**/
private static final int ARROW_SIZE = 13;

/***SwitchButton默认宽*/
private static final int SWITCHBUTTON_WIDTH = 50;

/***SwitchButton默认高*/
private static final int SWITCHBUTTON_HEIGHT = 28;

/**头标**/
private Drawable headerDrawable;

/**头标宽**/
private int headerDrawableWidth;
/**头标高**/
private int headerDrawableHeight;

/**距离左边缘的距离**/
private int paddingLeft;

/**距离右边缘的距离**/
private int paddingRight;

/**绘制头标时,画布在Y轴的绘制偏移量**/
private float headerDrawableStartDrawY;

/**文字与图片间的距离**/
private int drawablePadding = -1;

/**头部文字提示**/
private String textHeader;

/**文字颜色**/
private int textHeaderColor = Color.parseColor("#5a5a5a");

/**文字大小**/
private int textSize = -1;

/**文字绘制时,画布在Y轴的绘制偏移量**/
private float textStartDrawY;

/**绘制文字的画笔**/
private Paint textPaint;

/** 尾部 > 图片**/
private Drawable arrowDrawable;
/**尾部 > 大小**/
private int arrowSize = -1;

/** > 绘制的X轴偏移量**/
private float arrowStartDrawX;

/** > 绘制的Y轴偏移量**/
private float arrowStartDrawY;

/**footerDrawable != null 时,绘制的时候是否按照原图片大小绘制**/
private boolean arrowWropToSelf = true;

/**尾部宽**/
private int arrowDrawableWidth;
/**尾部高**/
private int arrowDrawableHeight;

/**绘制arrow画笔**/
private Paint arrowPaint;

/**arrowPaint 颜色**/
private int arrowColor = Color.parseColor("#5a5a5a");

private DisplayMetrics dm;

/*以下是绘制SwitchButton所用到的参数*/

private Style style = Style.CUSTOM_ITEM;

/**默认宽**/
private int switchButtonWidth = -1;

/**默认高**/
private int switchButtonHeight = -1;

private static final long DELAYDURATION = 10;

/**开启颜色**/
private int onColor = Color.parseColor("#4ebb7f");
/**关闭颜色**/
private int offColor = Color.parseColor("#dadbda");
/**灰色带颜色**/
private int areaColor = Color.parseColor("#dadbda");
/**手柄颜色**/
private int handlerColor = Color.parseColor("#ffffff");
/**边框颜色**/
private int borderColor = offColor;
/**开关状态**/
private boolean toggleOn = false;
/**边框宽**/
private int borderWidth = 2;
/**纵轴中心**/
private float centerY;
/**按钮水平方向开始、结束的位置**/
private float startX,endX;
/**手柄x轴方向最小、最大值**/
private float handlerMinX,handlerMaxX;
/**手柄大小**/
private int handlerSize;
/**手柄在x轴的坐标位置**/
private float handlerX;
/**关闭时内部灰色带宽度**/
private float areaWidth;
/**是否使用动画效果**/
private boolean animate = true;
/**是否默认处于打开状态**/
private boolean defaultOn = true;
/**按钮半径**/
private float radius;

/**整个switchButton的区域**/
private RectF switchRectF = new RectF();

/**绘制switchButton的画笔**/
private Paint switchPaint;

private OnToggleChangedListener mListener;

private Handler mHandler = new Handler();

private double currentDelay;

private float downX = 0;

/**switchButton在X轴绘制的偏移量**/
private float switchButtonDrawStartX;

/**switchButton在Y轴绘制的偏移量**/
private float switchButtonDrawStartY;

/**分割线,默认在底部绘制**/
private Drawable dividerr;

/**分割线绘制的宽**/
private int dividerWidth = 2;

/**是否需要绘制分割线**/
private boolean dividerVisibilty = true;

/**触摸事件是否完成**/
private boolean touchDownEnd = false;

public MenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup(attrs);
}
public MenuItemView(Context context, AttributeSet attrs) {
super(context, attrs);
setup(attrs);
}

/**
* 初始化控件,获取相关的控件属性
* @param attrs
*/
private void setup(AttributeSet attrs){

dm = Resources.getSystem().getDisplayMetrics();

TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MenuItemView);
if(typedArray != null){
int count = typedArray.getIndexCount();
for(int i = 0;i < count;i++){
int attr = typedArray.getIndex(i);
switch (attr){
case R.styleable.MenuItemView_headerDrawable:
headerDrawable = typedArray.getDrawable(attr);
break;
case R.styleable.MenuItemView_drawPadding:
drawablePadding = typedArray.getDimensionPixelSize(attr,drawablePadding);
break;
case R.styleable.MenuItemView_textHeader:
textHeader = typedArray.getString(attr);
break;
case R.styleable.MenuItemView_textHeaderColor:
textHeaderColor = typedArray.getColor(attr, textHeaderColor);
break;
case R.styleable.MenuItemView_textSize:
textSize = typedArray.getDimensionPixelSize(attr, textSize);
break;
case R.styleable.MenuItemView_arrowDrawable:
arrowDrawable = typedArray.getDrawable(attr);
break;
case R.styleable.MenuItemView_arrowSize:
arrowSize = typedArray.getDimensionPixelSize(attr, arrowSize);
break;
case R.styleable.MenuItemView_arrowWropToSelf:
arrowWropToSelf = typedArray.getBoolean(attr, true);
break;
case R.styleable.MenuItemView_arrowColor:
arrowColor = typedArray.getColor(attr, arrowColor);
break;
case R.styleable.MenuItemView_onColor:
onColor = typedArray.getColor(attr, onColor);
break;
case R.styleable.MenuItemView_offColor:
borderColor = offColor = typedArray.getColor(attr,offColor);
break;
case R.styleable.MenuItemView_areaColor:
areaColor = typedArray.getColor(attr, areaColor);
break;
case R.styleable.MenuItemView_handlerColor:
handlerColor = typedArray.getColor(attr, handlerColor);
break;
case R.styleable.MenuItemView_bordeWidth:
borderWidth = typedArray.getColor(attr, borderWidth);
break;
case R.styleable.MenuItemView_animate:
animate = typedArray.getBoolean(attr, animate);
break;
case R.styleable.MenuItemView_defaultOn:
defaultOn = typedArray.getBoolean(attr, defaultOn);
break;
case R.styleable.MenuItemView_Style:
style = Style.getValue(typedArray.getInt(attr, Style.CUSTOM_ITEM.ordinal()));
break;
case R.styleable.MenuItemView_switchButtonWidth:
switchButtonWidth = typedArray.getDimensionPixelOffset(attr, switchButtonWidth);
break;
case R.styleable.MenuItemView_switchButtonHeight:
switchButtonHeight = typedArray.getDimensionPixelOffset(attr, switchButtonHeight);
break;
case R.styleable.MenuItemView_dividerr:
dividerr = typedArray.getDrawable(attr);
break;
case R.styleable.MenuItemView_dividerWidth:
dividerWidth = typedArray.getDimensionPixelOffset(attr,dividerWidth);
break;
case R.styleable.MenuItemView_dividerVisibilty:
dividerVisibilty = typedArray.getBoolean(attr,dividerVisibilty);
break;
}
}
typedArray.recycle();
}

② android removeView用法

直接给你上代码吧,写了我半个小时,经过了我的测试了的~

运行下就能看到结果了~关键的remove的时候有给你写注释~

布局的layout文件内容:
----------------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="@+id/linearlayout">

<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:layout_height="wrap_content" android:id="@+id/add"
android:text="Add" android:layout_width="100px"></Button>
<Button android:layout_height="wrap_content"
android:layout_width="100px" android:text="Remove" android:id="@+id/remove"></Button>
</LinearLayout>
<TextView android:id="@+id/TextView01" android:text="This is textView."
android:layout_width="fill_parent" android:gravity="center"
android:layout_height="50px"></TextView>

</LinearLayout>
----------------------------------------------------------------------------------

对应Activity的内容:
----------------------------------------------------------------------------------
package com.foxconn.dialog;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;

public class DialogTest extends Activity implements OnClickListener {

private Button add_btn, remove_btn;
private LinearLayout linearLayout;
private int index = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViews();
register();
}

private void register() {
add_btn.setOnClickListener(this);
remove_btn.setOnClickListener(this);
}

private void findViews() {
add_btn = (Button) findViewById(R.id.add);
remove_btn = (Button) findViewById(R.id.remove);
linearLayout = (LinearLayout) findViewById(R.id.linearlayout);
}

protected View createView() {
Button btn = new Button(this);
btn.setId(index++);
btn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
btn.setText("aaaaaa" + index);
return btn;
}

private void removeView() {
//获取linearlayout子view的个数
int count = linearLayout.getChildCount();
//研究整个LAYOUT布局,第0位的是含add和remove两个button的layout
//第count-1个是那个文字被置中的textview
//因此,在remove的时候,只能操作的是0<location<count-1这个范围的
//在执行每次remove时,我们从count-2的位置即textview上面的那个控件开始删除~
if (count - 2 > 0) {
//count-2>0用来判断当前linearlayout子view数多于2个,即还有我们点add增加的button
linearLayout.removeViewAt(count - 2);
}
}

public void onClick(View v) {
switch (v.getId()) {
case R.id.add:
linearLayout.addView(createView(), 1);
break;
case R.id.remove:
removeView();
break;
default:
break;
}
}
}
----------------------------------------------------------------------------------

③ Android 重学系列 View的绘制流程(六) 硬件渲染(上)

本文开始聊聊Android中的硬件渲染。如果跟着我的文章顺序,从SF进程到App进程的绘制流程一直阅读,我们到这里已经有了一定的基础,可以试着进行横向比对如Chrome浏览器渲染流程,看看软件渲染,硬件渲染,SF合成都做了什么程度的优化。

先让我们回顾一下负责硬件渲染的主体对象ThreadedRenderer在整个绘制流程中做了哪几个步骤。

在硬件渲染的过程中,有一个很核心的对象RenderNode,作为每一个View绘制的节点对象。

当每一次进行准备进行绘制的时候,都会雷打不动执行如下三个步骤:

如果遇到什么问题欢迎来到 https://www.jianshu.com/p/c84bfa909810 下进行讨论

实际上整个硬件渲染的设计还是比较庞大。因此本文先聊聊ThreadedRender整个体系中主要对象的构造以及相关的原理。

首先来认识下面几个重要的对象有一个大体的印象。

在Java层中面向Framework中,只有这么多,下面是一一映射的简图。

能看到实际上RenderNode也会跟着View 树的构建同时一起构建整个显示层级。也是因此ThreadedRender也能以RenderNode为线索构建出一套和软件渲染一样的渲染流程。

仅仅这样?如果只是这么简单,知道我习惯的都知道,我喜欢把相关总结写在最后。如果把总揽写在正文开头是因为设计比较繁多。因为我们如果以流水线的形式进行剖析容易造成迷失细节的困境。

让我继续介绍一下,在硬件渲染中native层的核心对象。

如下是一个思维导图:

有这么一个大体印象后,就不容易迷失在源码中。我们先来把这些对象的实例化以及上面列举的ThreadedRenderer在ViewRootImpl中执行行为的顺序和大家来聊聊其原理,先来看看ThreadedRenderer的实例化。

当发现mSurfaceHolder为空的时候会调用如下函数:

而这个方法则调用如下的方法对ThreadedRenderer进行创建:

文件:/ frameworks / base / core / java / android / view / ThreadedRenderer.java

能不能创建的了ThreadedRenderer则决定于全局配置。如果ro.kernel.qemu的配置为0,说明支持OpenGL 则可以直接返回true。如果qemu.gles为-1说明不支持OpenGL es返回false,只能使用软件渲染。如果设置了qemu.gles并大于0,才能打开硬件渲染。

我们能看到ThreadedRenderer在初始化,做了三件事情:

关键是看1-3点中ThreadRenderer都做了什么。

文件:/ frameworks / base / core / jni / android_view_ThreadedRenderer.cpp

能看到这里是直接实例化一个RootRenderNode对象,并把指针的地址直接返回。

能看到RootRenderNode继承了RenderNode对象,并且保存一个JavaVM也就是我们所说的Java虚拟机对象,一个java进程全局只有一个。同时通过getForThread方法,获取ThreadLocal中的Looper对象。这里实际上拿的就是UI线程的Looper。

在这个构造函数有一个mDisplayList十分重要,记住之后会频繁出现。接着来看看RenderNode的头文件:
文件:/ frameworks / base / libs / hwui / RenderNode.h

实际上我把几个重要的对象留下来:

文件:/ frameworks / base / core / java / android / view / RenderNode.java

能看到很简单,就是包裹一个native层的RenderNode返回一个Java层对应的对象开放Java层的操作API。

能看到这个过程生成了两个对象:

这个对象实际上让RenderProxy持有一个创建动画上下文的工厂。RenderProxy可以通过ContextFactoryImpl为每一个RenderNode创建一个动画执行对象的上下文AnimationContextBridge。

文件:/ frameworks / base / libs / hwui / renderthread / RenderProxy.cpp

在这里有几个十分重要的对象被实例化,当然这几个对象在聊TextureView有聊过( SurfaceView和TextureView 源码浅析 ):

我们依次看看他们初始化都做了什么。

文件:/ frameworks / base / libs / hwui / renderthread / RenderThread.cpp

能看到其实就是简单的调用RenderThread的构造函数进行实例化,并且返回对象的指针。

RenderThread是一个线程对象。先来看看其头文件继承的对象:
文件:/ frameworks / base / libs / hwui / renderthread / RenderThread.h

其中RenderThread的中进行排队处理的任务队列实际上是来自ThreadBase的WorkQueue对象。

文件:/ frameworks / base / libs / hwui / thread / ThreadBase.h

ThreadBase则是继承于Thread对象。当调用start方法时候其实就是调用Thread的run方法启动线程。

另一个更加关键的对象,就是实例化一个Looper对象到WorkQueue中。而直接实例化Looper实际上就是新建一个Looper。但是这个Looper并没有获取当先线程的Looper,这个Looper做什么的呢?下文就会揭晓。

WorkQueue把一个Looper的方法指针设置到其中,其作用可能是完成了某一件任务后唤醒Looper继续工作。

而start方法会启动Thread的run方法。而run方法最终会走到threadLoop方法中,至于是怎么走进来的,之后有机会会解剖虚拟机的源码线程篇章进行讲解。

在threadloop中关键的步骤有如下四个:

在这个过程中创建了几个核心对象:

另一个核心的方法就是,这个方法为WorkQueue的Looper注册了监听:

能看到在这个Looper中注册了对DisplayEventReceiver的监听,也就是Vsync信号的监听,回调方法为displayEventReceiverCallback。

我们暂时先对RenderThread的方法探索到这里,我们稍后继续看看回调后的逻辑。

文件:/ frameworks / base / libs / hwui / thread / ThreadBase.h

能看到这里的逻辑很简单实际上就是调用Looper的pollOnce方法,阻塞Looper中的循环,直到Vsync的信号到来才会继续往下执行。详细的可以阅读我写的 Handler与相关系统调用的剖析 系列文章。

文件:/ frameworks / base / libs / hwui / thread / ThreadBase.h

实际上调用的是WorkQueue的process方法。

文件:/ frameworks / base / libs / hwui / thread / WorkQueue.h

能看到这个过程中很简单,几乎和Message的loop的逻辑一致。如果Looper的阻塞打开了,则首先找到预计执行时间比当前时刻都大的WorkItem。并且从mWorkQueue移除,最后添加到toProcess中,并且执行每一个WorkItem的work方法。而每一个WorkItem其实就是通过从某一个压入方法添加到mWorkQueue中。

到这里,我们就明白了RenderThread中是如何消费渲染任务的。那么这些渲染任务又是哪里诞生呢?

上文聊到了在RenderThread中的Looper会监听Vsync信号,当信号回调后将会执行下面的回调。

能看到这个方法的核心实际上就是调用drainDisplayEventQueue方法,对ui渲染任务队列进行处理。

能到在这里mVsyncRequested设置为false,且mFrameCallbackTaskPending将会设置为true,并且调用queue的postAt的方法执行ui渲染方法。

还记得queue实际是是指WorkQueue,而WorkQueue的postAt方法实际实现如下:
/ frameworks / base / libs / hwui / thread / WorkQueue.h

情景带入,当一个Vsync信号达到Looper的监听者,此时就会通过WorkQueue的drainDisplayEventQueue 压入一个任务到队列中。

每一个默认的任务都是执行dispatchFrameCallback方法。这里的判断mWorkQueue中是否存在比当前时间更迟的时刻,并返回这个WorkItem。如果这个对象在头部needsWakeup为true,说明可以进行唤醒了。而mWakeFunc这个方法指针就是上面传下来:

把阻塞的Looper唤醒。当唤醒后就继续执行WorkQueue的process方法。也就是执行dispatchFrameCallbacks方法。

在这里执行了两个事情:

先添加到集合中,在上面提到过的threadLoop中,会执行如下逻辑:

如果大小不为0,则的把中的IFrameCallback全部迁移到mFrameCallbacks中。

而这个方法什么时候调用呢?稍后就会介绍。其实这部分的逻辑在TextureView的解析中提到过。

接下来将会初始化一个重要对象:

这个对象名字叫做画布的上下文,具体是什么上下文呢?我们现在就来看看其实例化方法。
文件:/ frameworks / base / libs / hwui / renderthread / CanvasContext.cpp

文件:/ device / generic / goldfish / init.ranchu.rc

在init.rc中默认是opengl,那么我们就来看看下面的逻辑:

首先实例化一个OpenGLPipeline管道,接着OpenGLPipeline作为参数实例化CanvasContext。

文件:/ frameworks / base / libs / hwui / renderthread / OpenGLPipeline.cpp

能看到在OpenGLPipeline中,实际上就是存储了RenderThread对象,以及RenderThread中的mEglManager。透过OpenGLPipeline来控制mEglManager进而进一步操作OpenGL。

做了如下操作:

文件:/ frameworks / base / libs / hwui / renderstate / RenderState.cpp

文件:/ frameworks / base / libs / hwui / renderthread / DrawFrameTask.cpp

实际上就是保存这三对象RenderThread;CanvasContext;RenderNode。

文件:/ frameworks / base / core / jni / android_view_ThreadedRenderer.cpp

能看到实际上就是调用RenderProxy的setName方法给当前硬件渲染对象设置名字。

文件:/ frameworks / base / libs / hwui / renderthread / RenderProxy.cpp

能看到在setName方法中,实际上就是调用RenderThread的WorkQueue,把一个任务队列设置进去,并且调用runSync执行。

能看到这个方法实际上也是调用post执行排队执行任务,不同的是,这里使用了线程的Future方式,阻塞了执行,等待CanvasContext的setName工作完毕。

④ android.support.v4.view.pagertabstrip什么意思

PagerTabStrip这个控件现在很少使用了,现在都是使用viewpager+tablayout,下面是这两个配合的效果:

android学习手册包含9个章节,108个例子,源码文档随便看,例子都是可交互,可运行,源码采用android studio目录结构,高亮显示代码,文档都采用文档结构图显示,可以快速定位。360手机助手中下载

PagerTabStrip是ViewPager的一个关于当前页面、上一个页面和下一个页面的一个非交互的指示器。它经常作为ViewPager控件的一个子控件被被添加在XML布局文件中。在你的布局文件中,将它作为子控件添加在ViewPager中。而且要将它的 android:layout_gravity 属性设置为TOP或BOTTOM来将它显示在ViewPager的顶部或底部。每个页面的标题是通过适配器的getPageTitle(int)函数提供给ViewPager的。

1、XML布局文件:


[html] view plain print?

<RelativeLayoutxmlns: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"

tools:context="com.example.testviewpage_2.MainActivity">

<android.support.v4.view.ViewPager

android:id="@+id/viewpager"

android:layout_width="wrap_content"

android:layout_height="200dip"

android:layout_gravity="center">

<android.support.v4.view.PagerTitleStrip

android:id="@+id/pagertitle"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="top"

/>

</android.support.v4.view.ViewPager>

</RelativeLayout>

<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"
tools:context="com.example.testviewpage_2.MainActivity" >

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="200dip"
android:layout_gravity="center">

<android.support.v4.view.PagerTitleStrip
android:id="@+id/pagertitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
/>

</android.support.v4.view.ViewPager>

</RelativeLayout>

清楚的看到我们将.PagerTitleStrip将其作为ViewPager的子控件直接嵌入其中;这是第一步;当然android:layout_gravity=""的值要设置为top或bottom。将标题栏显示在顶部或底部。



2、重写适配器的getPageTitle()函数

便于大家有个整体认识,先贴全局代码,然后再逐个讲,这段代码是在《ViewPager 详解(二)---详解四大函数》直接更改来的,如果不太明白,先看看这篇文章。



[java] view plain print?

packagecom.example.testviewpage_2;

/**

*@authorharvic

*@date2014.8.12

*/

importjava.util.ArrayList;

importjava.util.List;

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.support.v4.view.PagerAdapter;

importandroid.support.v4.view.PagerTitleStrip;

importandroid.support.v4.view.ViewPager;

importandroid.view.LayoutInflater;

importandroid.view.View;

importandroid.view.ViewGroup;

{

privateViewview1,view2,view3;

privateList<View>viewList;//view数组

privateViewPagerviewPager;//对应的viewPager

privateList<String>titleList;//标题列表数组

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

viewPager=(ViewPager)findViewById(R.id.viewpager);

LayoutInflaterinflater=getLayoutInflater();

view1=inflater.inflate(R.layout.layout1,null);

view2=inflater.inflate(R.layout.layout2,null);

view3=inflater.inflate(R.layout.layout3,null);

viewList=newArrayList<View>();//将要分页显示的View装入数组中

viewList.add(view1);

viewList.add(view2);

viewList.add(view3);

titleList=newArrayList<String>();//每个页面的Title数据

titleList.add("王鹏");

titleList.add("姜语");

titleList.add("结婚");

PagerAdapterpagerAdapter=newPagerAdapter(){

@Override

publicbooleanisViewFromObject(Viewarg0,Objectarg1){

//TODOAuto-generatedmethodstub

//根据传来的key,找到view,判断与传来的参数Viewarg0是不是同一个视图

returnarg0==viewList.get((int)Integer.parseInt(arg1.toString()));

}

@Override

publicintgetCount(){

//TODOAuto-generatedmethodstub

returnviewList.size();

}

@Override

publicvoiddestroyItem(ViewGroupcontainer,intposition,

Objectobject){

//TODOAuto-generatedmethodstub

container.removeView(viewList.get(position));

}

@Override

publicObjectinstantiateItem(ViewGroupcontainer,intposition){

//TODOAuto-generatedmethodstub

container.addView(viewList.get(position));

//把当前新增视图的位置(position)作为Key传过去

returnposition;

}

@Override

(intposition){

//TODOAuto-generatedmethodstub

returntitleList.get(position);

}

};

viewPager.setAdapter(pagerAdapter);

}

}

⑤ 如何通过View对象复制一个一模一样的View

RZCellSizeManager,除了使用systemLayoutSizeFittingSize:外,还支持高度的缓存等vip功能。对于复杂的动态cell,性能提升比较明显。该库仅支持iOS7.x、8.x,慎入。 题主的问题2:cell中数量不确定的多张imageView该如何处理

⑥ android中,怎样实现textView长按出现复制,出现复制、转发按钮

实现textiew长按事件,按键区事先定义,平时隐藏,长按时显示即可

⑦ android如何深度克隆View对象

用java的反射,试试

⑧ Android textView 复制问题

方法一:在布局文件的TextView控件属性中增加一句:android:textIsSelectable="true"
方法二:直接上代码
<LinearLayout 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:gravity="center" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:background="#80FF00"
android:gravity="center"
android:text="长按此处跳出复制选框"
android:textColor="#000000" />
</LinearLayout>
</LinearLayout>

package com.example.test;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.text.ClipboardManager;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView tv;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
tv.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View arg0) {
test();
return false;
}
});
}
public Dialog test() {
Dialog dialog = new AlertDialog.Builder(this).setTitle("提示")
.setNegativeButton("取消", null)
.setItems(new String[] { "复制" }, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String string = tv.getText().toString();
(string, getBaseContext());
Toast.makeText(getBaseContext(), "文本已复制到粘贴板", 2000)
.show();
}
}).create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();
return dialog;
}
public static void (String content, Context context) {
// 得到剪贴板管理器
ClipboardManager cmb = (ClipboardManager) context
.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setText(content.trim());
}
}

阅读全文

与android复制view相关的资料

热点内容
找漫画看应该下载什么app 浏览:180
如何在vps上搭建自己的代理服务器 浏览:744
nginxphp端口 浏览:403
内脏pdf 浏览:152
怎么看云服务器架构 浏览:85
我的世界国际服为什么登不进服务器 浏览:996
微盟程序员老婆 浏览:930
intellij创建java 浏览:110
java连接odbc 浏览:38
启动修复无法修复电脑命令提示符 浏览:359
手机编程是什么 浏览:98
山东移动程序员 浏览:163
苏州java程序员培训学校 浏览:479
单片机液晶驱动 浏览:855
魔拆app里能拆到什么 浏览:132
新预算法的立法理念 浏览:144
wdcpphp的路径 浏览:135
单片机p0口电阻 浏览:926
浏览器中调短信文件夹 浏览:594
五菱宏光空调压缩机 浏览:70