導航:首頁 > 操作系統 > 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相關的資料

熱點內容
android點贊功能 瀏覽:326
露鳥同志電影 瀏覽:279
《外出》未刪減版韓國 瀏覽:14
外出完整140分鍾版本 瀏覽:728
香港電影走光 瀏覽:328
初級初中生編程 瀏覽:697
在阿姨鬼混還是鬼片 瀏覽:127
老年人愛愛的電影 瀏覽:900
與365dni類似的電影推薦 瀏覽:986
伺服器上的soc什麼意思 瀏覽:885
朱藝彬年輕的姐夫 瀏覽:396
怎麼刪除梅花視頻 瀏覽:361
尋緣app在哪裡下載 瀏覽:301
男同激情電影 瀏覽:392
macpdf轉換成word 瀏覽:584
框架柱尺寸加密 瀏覽:731
韓國電影一男的做鴨 瀏覽:488
女主和爸爸哥哥在一起的小說 瀏覽:730
伺服器什麼時候買最便宜 瀏覽:786
最刺激的床戲電影 瀏覽:752