Android High Imitation micro-chat list sliding Delete effect _android

Source: Internet
Author: User
Tags abs gety static class

Preface

With the micro-mail know that the micro-letter dialog list Sliding Delete effect is very good, this effect we can have. The idea is actually very simple, get a ListView, and then each item inside can be a sliding custom control. Because the ListView is sliding up and down and the item is sliding around, there will be a sliding conflict, maybe you need to know the distribution of the Click event in Android, please refer to the Android Source analysis-click event Distribution mechanism. My solution is this: rewrite ListView's Onintercepttouchevent method, make a judgment when moving, and return False if it is left or right, otherwise true Override the Ontouchevent method of the Slideview (that is, the custom item control) to handle the slide. The whole idea no problem, sliding conflict also resolved, but ListView can not get focus, that is, ListView can not handle the click event. Let's recall what the problem is: My understanding is that there is no problem with the above processing slide itself, but one side effect is that the outer view loses focus and cannot handle the click event. Common sliding conflict scenarios, such as launcher internal embedding ListView, are no problem, because this time launcher does not need to gain focus, the focus is the internal ListView. Therefore, the above approach is not appropriate for the external need to gain focus (for example, external ListView). So I and Ttdevs to explore, found that he used another way of thinking, I never thought I could play like this. Here is a description of his ideas.

New Way of thinking

Do not consider so complex, do not use the mainstream play, all events by the outer listview do intercept, while the event passed to Slideview to do the sliding, this implementation can indeed achieve results, and the code is very simple, there is no need to deal with any complex sliding conflict.

effect

The following are micro-letters and high imitation effects

Code Analysis

Let's see how Slideview is achieved.

See Layout xml:

<?xml version= "1.0" encoding= "Utf-8"?> <merge xmlns:android= "Http://schemas.android.com/apk/res/android" Android:layout_width= "Match_parent" android:layout_height= "match_parent" > <linearlayout android:id= "@+id/v" Iew_content "android:layout_width=" match_parent "android:layout_height=" match_parent "android:orientation=" hor
    Izontal "> </LinearLayout> <relativelayout android:id=" @+id/holder "android:layout_width=" 120DP "

    android:layout_height= "Match_parent" android:clickable= "true" android:background= "@drawable/holder_bg" > <textview android:id= "@+id/delete" android:layout_width= wrap_content "android:layout_height=" Wrap_ Content "android:drawableleft=" @drawable/del_icon_normal "android:layout_centerinparent= true" android:g ravity= "center" android:textcolor= "@color/floralwhite" android:text= "delete"/> </RelativeLayout> <
 /merge>

In the XML file above, all the view will be placed in the view_content, and holder is to place things such as the delete button, our slideview will load the layout.

Look again Slideview.java:

 /** * Slideview inherits from LinearLayout */public class Slideview extends LinearLayout {private static final String TAG =

  "Slideview";

  Private context Mcontext;

  A container used to place all view private linearlayout mviewcontent;

  The container used to place the built-in view, such as Delete button private relativelayout mholder;

  Elastic sliding object, providing elastic sliding effect private scroller mscroller;

  The sliding callback interface is used to inform the upper layer of the sliding event private Onslidelistener monslidelistener;

  The width unit of the built-in container: DP private int mholderwidth = 120;
  Record the last sliding coordinates private int mlastx = 0 respectively;

  private int mlasty = 0;

  Used to control the sliding angle, only when the angle a satisfies the following conditions to slide: tan a = deltax/deltay > 2 private static final int tan = 2;
    Public interface Onslidelistener {//Slideview three states: Start sliding, open, close public static final int slide_status_off = 0;
    public static final int slide_status_start_scroll = 1;

    public static final int slide_status_on = 2; 
     /** * @param View * Current Slideview * @param status * slide_status_on, Slide_status_off or * SlidE_status_start_scroll */public void onslide (view view, int STATUS);
    Public Slideview {Super (context);
  Initview ();
    Public Slideview (context, AttributeSet attrs) {Super (context, attrs);
  Initview ();
    private void Initview () {mcontext = GetContext ();
    Initialize the elastic sliding object mscroller = new Scroller (mcontext);
    setting its direction to transverse setorientation (linearlayout.horizontal);
    Load the Slide_view_merge in View.inflate (Mcontext, R.layout.slide_view_merge, this);
    Mviewcontent = (linearlayout) Findviewbyid (r.id.view_content);
            Mholderwidth = Math.Round (Typedvalue.applydimension (Typedvalue.complex_unit_dip, Mholderwidth, GetResources ()
  . Getdisplaymetrics ()); //Set button content, also can set icon what, I did not write public void SetButtonText (charsequence text) {(TextView) Findviewbyid (R.id.delete)).
  SetText (text); ///Add view to public void Setcontentview (view view) {Mviewcontent.addview in viewcontent); 
  }//Set sliding callback public void Setonslidelistener (Onslidelistener onslidelistener) {monslidelistener = Onslidelistener;
    ///Set the current state to turn off public void shrink () {if (GETSCROLLX ()!= 0) {this.smoothscrollto (0, 0); }///Sliding according to Motionevent, this method is equivalent to Ontouchevent//If you do not need to handle sliding conflicts, you can rename them directly so that you can work normally with public void onrequiretouchevent (
    Motionevent event) {int x = (int) event.getx ();
    int y = (int) event.gety ();
    int scrollx = GETSCROLLX ();

    LOG.D (TAG, "x=" + x + "y=" + y); Switch (event.getaction ()) {case Motionevent.action_down: {if (!mscroller.isfinished ()) {Mscroller.ab
      Ortanimation (); } if (Monslidelistener!= null) {Monslidelistener.onslide (this, onslidelistener.slide_status_st
      Art_scroll);
    } break;
      Case Motionevent.action_move: {int deltax = X-MLASTX;
      int deltay = Y-mlasty; if (Math.Abs (DeltaX) < Math.Abs (deltay) * TAN) {//Sliding not satisfied barPieces, do not do transverse sliding break;
      //To calculate whether the sliding endpoint is legitimate, to prevent sliding cross-border int newscrollx = Scrollx-deltax;
        if (deltax!= 0) {if (Newscrollx < 0) {newscrollx = 0;
        else if (Newscrollx > Mholderwidth) {newscrollx = Mholderwidth;
      } this.scrollto (NEWSCROLLX, 0);
    } break;
      Case MOTIONEVENT.ACTION_UP: {int newscrollx = 0; Here it is judged that when the hand is released, it will automatically slide to both sides, specifically to which side of the slide, depending on where the current position if (Scrollx-mholderwidth * 0.75 > 0) {newscrollx = Mholde
      Rwidth;
      //slowly slide to the end This.smoothscrollto (newscrollx, 0); Notifies the upper-level sliding event if (Monslidelistener!= null) {Monslidelistener.onslide (this, newscrollx = = 0?)
      OnSlideListener.SLIDE_STATUS_OFF:OnSlideListener.SLIDE_STATUS_ON);
    } break;
    } Default:break;
    } MLASTX = x;
  Mlasty = y; } private void Smoothscrollto (int destx, int desty) {//slow scrolling to the specified position int scroLLX = Getscrollx ();
    int delta = DESTX-SCROLLX;
    With a three times-fold long slide toward the DESTX, the effect is to slide slowly mscroller.startscroll (scrollx, 0, Delta, 0, Math.Abs (Delta) * 3);
  Invalidate (); @Override public void Computescroll () {if (Mscroller.computescrolloffset ()) {Scrollto (Mscroller.getcurr
      X (), Mscroller.getcurry ());
    Postinvalidate ();
 }
  }

}

The above code to do a very detailed description, this is the complete code of the sliding control, we should understand that: you add the view is added to the slideview of the view:view_content, rather than directly in the Slideview, only in this way we can easily do sliding effect.

Then look at the ListView code: The core is the following method, the Click event sent to Slideview processing.

  @Override Public
  Boolean ontouchevent (Motionevent event) {
    switch (event.getaction ()) {
    case Motionevent.action_down: {
      int x = (int) event.getx ();
      int y = (int) event.gety ();
      We want to know which line of
      int position = pointtoposition (x, y) that is currently clicked;
      LOG.E (TAG, "postion=" + position);
      if (position!= invalid_position) {
        //Get the currently clicked row data to remove the item from the current row.
        //There may be some suspicion, why do you do this? Why not Getchildat (position)?
        //Because ListView will cache, if you do not do so, some rows of view you can not get.
        Messageitem data = (Messageitem) getitematposition (position);
        Mfocuseditemview = Data.slideview;
        LOG.E (TAG, "focuseditemview=" + Mfocuseditemview);
      }
    Default: Break
      ;
    }

    Send a sliding event request to the currently clicked view, which is actually sending the Slideview request
    if (Mfocuseditemview!= null) {
      Mfocuseditemview.onrequiretouchevent (event);
    }

    Return Super.ontouchevent (event);
  }

Last look at the activity code:

public class Mainactivity extends activity implements Onitemclicklistener, Onclicklistener, Onslidelistener {priv

  Ate static final String TAG = "mainactivity";

  Private Listviewcompat Mlistview;

  Private list<messageitem> Mmessageitems = new arraylist<mainactivity.messageitem> ();

  Private Slideadapter Mslideadapter;

  The last open state of the Slideview private Slideview Mlastslideviewwithstatuson;
    @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
    Setcontentview (R.layout.activity_main);
  Initview ();

    private void Initview () {Mlistview = (Listviewcompat) Findviewbyid (r.id.list);
      for (int i = 0; i < i++) {Messageitem item = new Messageitem ();
        if (i% 3 = 0) {item.iconres = R.drawable.default_qq_avatar;
        Item.title = "Tencent News";
        item.msg = "Qingdao Explosion Full Moon: A large number of fish and shrimp death";
      Item.time = "Evening 18:18";
      else {item.iconres = R.drawable.wechat_icon;  Item.title = "Micro-trust team";
        Item.msg = "You are welcome to use micro-letter";
      Item.time = "December 18";
    } mmessageitems.add (item);
    } mslideadapter = new Slideadapter ();
    Mlistview.setadapter (Mslideadapter);
  Mlistview.setonitemclicklistener (this);

    Private class Slideadapter extends Baseadapter {private Layoutinflater minflater;
      Slideadapter () {super ();
    Minflater = Getlayoutinflater ();
    @Override public int GetCount () {return mmessageitems.size ();
    @Override public Object getitem (int position) {return mmessageitems.get (position);
    @Override public long getitemid (int position) {return position;
      @Override public View getview (int position, View Convertview, ViewGroup parent) {Viewholder holder;
      Slideview Slideview = (slideview) Convertview;

   if (Slideview = = null) {//Here is our item View Itemview = minflater.inflate (R.layout.list_item, NULL);     Slideview = new Slideview (mainactivity.this);
        Here Add item to Slideview Slideview.setcontentview (Itemview);
        Here is doing some data caching holder = new Viewholder (Slideview);
        Slideview.setonslidelistener (Mainactivity.this);
      Slideview.settag (holder);
      else {holder = (Viewholder) slideview.gettag ();
      } Messageitem item = mmessageitems.get (position);
      Item.slideview = Slideview;

      Item.slideView.shrink ();
      Holder.icon.setImageResource (Item.iconres);
      Holder.title.setText (Item.title);
      Holder.msg.setText (ITEM.MSG);
      Holder.time.setText (Item.time);

      Holder.deleteHolder.setOnClickListener (Mainactivity.this);
    return slideview;
    } public class Messageitem {public int iconres;
    Public String title;
    Public String msg;
    public String time;
  Public Slideview Slideview;
    private static class Viewholder {public ImageView icon;
    Public TextView title; PuBlic TextView msg;
    public TextView time;

    Public ViewGroup Deleteholder;
      Viewholder (view view) {icon = (ImageView) View.findviewbyid (R.id.icon);
      title = (TextView) View.findviewbyid (r.id.title);
      msg = (TextView) View.findviewbyid (r.id.msg);
      Time = (TextView) View.findviewbyid (r.id.time);
    Deleteholder = (viewgroup) View.findviewbyid (R.id.holder);  @Override public void Onitemclick (adapterview<?> parent, view view, int position, long ID) {//
  Here handle ListItem Click event log.e (TAG, "Onitemclick position=" + position); @Override public void Onslide (view view, int status) {//If a slideview is currently open, close it if Mlastslideviewwit
    Hstatuson!= null && mlastslideviewwithstatuson!= view) {Mlastslideviewwithstatuson.shrink ();
    //record this time in the Open view if (status = = slide_status_on) {Mlastslideviewwithstatuson = (slideview) view; @Override public void OnClick (View v){//Here is the Click event to handle the Delete button, you can delete the dialog if (v.getid () = = R.id.holder) {int position = Mlistview.getpositionforview (v);
        if (position!= listview.invalid_position) {mmessageitems.remove (position);
      Mslideadapter.notifydatasetchanged ();
    LOG.E (TAG, "OnClick v=" + V);
 }
  }
}

Code I have written a note, I do not say more.

Code Download: Http://xiazai.jb51.net/201608/yuanma/androidSlide (jb51.net). rar

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.