可實(shí)現(xiàn)頭部圖片下拉放大RecyclerView

實(shí)現(xiàn)頭部放下拉放大RecyclerView
  • 項(xiàng)目需求需要實(shí)現(xiàn)頭部圖片可下拉放大效果, 網(wǎng)上搜到很多都是自定義scrollView來實(shí)現(xiàn)凶伙,這種方式也可以實(shí)現(xiàn)所需要的效果郭毕,但是當(dāng)與RecyclerView配合使用時(shí),會(huì)一次性加載RecyclerView 中的所有數(shù)據(jù)函荣,著樣總是感覺不太好显押,并且我希望是的是整個(gè)頁面只使用RecyclerView,而不是使用ScrollView 進(jìn)行包裹傻挂, 所以決定還是自定義一個(gè)RecyclerView乘碑。


    pic
實(shí)現(xiàn)思路
  • 無非就是重寫onTouchEvent方法,再將需要控制放大縮小的view 傳遞給自身即可金拒。
直接上代碼
/**
 * Created by lsh on 2018/4/24.
 */
public class MyRecyclerView extends RecyclerView {
    private static final String TAG = "MyRecyclerView";
    private LinearLayoutManager mLayoutManager;
    private int mTouchSlop;
    private View zoomView;
    // 記錄首次按下位置
    private float mFirstPosition = 0;
    // 是否正在放大
    private Boolean mScaling = false;

    LinearLayoutManager mLinearLayoutManager ;
    private int screenWidth;

    public MyRecyclerView(Context context) {
        this(context, null);
    }
    public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mLayoutManager = new LinearLayoutManager(context);
        setLayoutManager(mLayoutManager);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }
    public void setZoomView(View v, LinearLayoutManager linearLayoutManager) {
        //獲取屏幕寬度
        screenWidth = ScreenUtils.getScreenWidth();
        //此處我的圖片命名為img兽肤,大家根據(jù)實(shí)際情況修改
        ImageView img =(ImageView)v.findViewById(R.id.img);
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) img.getLayoutParams();
        //獲取屏幕寬度
        lp.width =screenWidth;
        //設(shè)置寬高比為16:9
        lp.height = screenWidth * 9 / 16;
        //給imageView重新設(shè)置寬高屬性
        img.setLayoutParams(lp);
        this.zoomView = img;
        mLinearLayoutManager = linearLayoutManager ;

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if(zoomView !=null){
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) zoomView.getLayoutParams();
            //判斷觸摸事件
            switch (event.getAction()) {
                //觸摸結(jié)束
                case MotionEvent.ACTION_UP:
                    mScaling = false;
                    replyImage();
                    break;
                //觸摸中
                case MotionEvent.ACTION_MOVE:
                    //判斷是否正在放大 mScaling 的默認(rèn)值為false
                    if (!mScaling) {
                        //當(dāng)圖片也就是第一個(gè)item完全可見的時(shí)候,記錄觸摸屏幕的位置
                        if (mLinearLayoutManager.findViewByPosition(mLinearLayoutManager.findFirstVisibleItemPosition()).getTop() == 0) {
                            //記錄首次按下位置
                            mFirstPosition = event.getY();
                        } else {
                            break;
                        }
                    }
                    // 滾動(dòng)距離乘以一個(gè)系數(shù)
                    int distance = (int) ((event.getY() - mFirstPosition) * 0.4);
                    if (distance < 0) {
                        break;
                    }
                    // 處理放大
                    mScaling = true;

                    lp.width = zoomView.getWidth() + distance;
                    lp.height = (zoomView.getWidth()  + distance) * 9 / 16;
                    System.out.println( "寬度是 =  " +  lp.width + "高度是" + lp.height);
                    // 設(shè)置控件水平居中(如果不設(shè)置绪抛,圖片的放大縮小是從圖片頂點(diǎn)開始)
                    ((ViewGroup.MarginLayoutParams) lp).setMargins(-(lp.width -screenWidth) / 2, 0, 0, 0);
                    zoomView.setLayoutParams(lp);
                    return true; // 返回true表示已經(jīng)完成觸摸事件资铡,不再處理
            }
        }

        return super.onTouchEvent(event);
    }


 /**
     * 圖片回彈動(dòng)畫
     */
    private void replyImage() {
        final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) zoomView.getLayoutParams();
        final float wPresent = zoomView.getLayoutParams().width;// 圖片當(dāng)前寬度
        final float hPresent = zoomView.getLayoutParams().height;// 圖片當(dāng)前高度

        final float width = screenWidth;// 圖片原寬度
        final float heigh = screenWidth * 9 / 16;// 圖片原高度

        // 設(shè)置動(dòng)畫
        ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration(200);

        anim.addUpdateListener(animation -> {
            float cVal = (Float) animation.getAnimatedValue();
            lp.width = (int) (wPresent- (wPresent- width ) * cVal);
            lp.height = (int) (hPresent - (hPresent - heigh ) * cVal);
            ((MarginLayoutParams) lp).setMargins(-(lp.width - screenWidth) / 2, 0, 0, 0);
            zoomView.setLayoutParams(lp);
        });
        anim.start();

    }


}

其中ScreenUtils 是 utilcode中提供的工具類

  • Java代碼
public class PullZoomActivity extends AppCompatActivity {
    private DisplayMetrics metric;
    private MyRecyclerView recy;
    private LinearLayoutManager mLinearLayoutManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pull_zoom);
        recy = (MyRecyclerView)findViewById(R.id.hehe);
        if (mLinearLayoutManager == null) {
            mLinearLayoutManager = new LinearLayoutManager(this);
        }

        TestAdpter testAdpter = new TestAdpter(R.layout.text, getData());
        recy.setLayoutManager(mLinearLayoutManager) ;
        recy.setAdapter(testAdpter);
        View view = getLayoutInflater().inflate(R.layout.header, (ViewGroup) recy.getParent(), false);
        testAdpter.addHeaderView(view);
        //給Recycle中傳遞需要控制的view
        recy.setZoomView(view , mLinearLayoutManager);
    }


    public List<String> getData() {

        ArrayList<String> lsit = new ArrayList<>();
        for (int i = 0; i <20 ; i++) {
            lsit.add("第" + i + "條數(shù)據(jù)") ;
        }
        return lsit;
    }
}

其中adapter 是使用BRVAH 的 BaseRecyclerViewAdapterHelper(強(qiáng)烈推薦,你值得擁有)我這里使用的是將Image放在頭部具中實(shí)現(xiàn)的幢码,當(dāng)然你也可以使用RecycleView的多布局笤休,只是相應(yīng)的你需要在adpter中判斷當(dāng)時(shí)第一條item時(shí) 執(zhí)行setZoomView 方法進(jìn)行view的傳遞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛤育,一起剝皮案震驚了整個(gè)濱河市调塌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌使碾,老刑警劉巖款筑,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異咕娄,居然都是意外死亡亥揖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來费变,“玉大人摧扇,你說我怎么就攤上這事≈科纾” “怎么了扛稽?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滑负。 經(jīng)常有香客問我在张,道長,這世上最難降的妖魔是什么矮慕? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任帮匾,我火速辦了婚禮,結(jié)果婚禮上痴鳄,老公的妹妹穿的比我還像新娘瘟斜。我一直安慰自己,他們只是感情好痪寻,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布螺句。 她就那樣靜靜地躺著,像睡著了一般槽华。 火紅的嫁衣襯著肌膚如雪壹蔓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天猫态,我揣著相機(jī)與錄音佣蓉,去河邊找鬼。 笑死亲雪,一個(gè)胖子當(dāng)著我的面吹牛勇凭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播义辕,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼虾标,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了灌砖?” 一聲冷哼從身側(cè)響起璧函,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎基显,沒想到半個(gè)月后蘸吓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撩幽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年库继,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了箩艺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宪萄,死狀恐怖艺谆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拜英,我是刑警寧澤静汤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站聊记,受9級(jí)特大地震影響撒妈,放射性物質(zhì)發(fā)生泄漏恢暖。R本人自食惡果不足惜排监,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杰捂。 院中可真熱鬧舆床,春花似錦、人聲如沸嫁佳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒿往。三九已至盛垦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓤漏,已是汗流浹背腾夯。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔬充,地道東北人蝶俱。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像饥漫,于是被迫代替她去往敵國和親榨呆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容