Projects Attribouter Wiki

Extending a Wedge

Since the wedges used in the layout file are referenced by their corresponding class name, you may have guessed that it is possible to create your own wedge similarly to how one would create a custom view. You would be correct in that assumption. That said, because there are so many different use cases for this, I'm not going to provide a full "tutorial", but rather explain the basics of how wedges can be created.

Creating the Class

The absolute minimum requirements for a wedge class are that they must extend me.jfenn.attribouter.wedges.Wedge and have a public constructor that accepts an android.content.res.XmlResourceParser. However, there are several additional suggestions that can affect... things... if they are not followed:

Here is a basic example of what has been described so far:

public class MyWedge extends Wedge<MyWedge.MyViewHolder> {
  
  public MyWedge(XmlResourceParser parser) {
    super(R.layout.my_wedge_layout);
    //get attributes
    addChildren(parser);
  }
  
  //other methods
  
  public static class MyViewHolder extends ViewHolder {
  
    public MyViewHolder(View v) {
      super(v);
    }
  
  }
  
}

Implementing Methods

There are also several abstract methods in Wedge that must be defined. Rather than explain all of them, I will simply implement them all in the above example along with comments explaining what should happen where.

public class MyWedge extends Wedge<MyWedge.MyViewHolder> {

  //define information in your Wedge class
  
  public MyWedge(XmlResourceParser parser) {
    super(R.layout.my_wedge_layout);
    //instantiate attributes
    addChildren(parser);
  }
  
  @Override
  public MyViewHolder getViewHolder(View v) { //"v" is the inflated layout file that you passed the resource of in your call to super()
    return new MyViewHolder(v); //yep, that's all you really need
  }
  
  @Override
  public void bind(Context context, MyViewHolder viewHolder) {
    //here you bind the data in your wedge class to the views in the MyViewHolder instance
  }
  
  public static class MyViewHolder extends ViewHolder {
  
    //define views in your layout
  
    public MyViewHolder(View v) {
      super(v);
      //instantiate views - "view = v.findViewById(...);"
    }
  
  }
  
}

GitHub Requests

If you wish to make a request to the GitHub API from your wedge, simply call addRequest(GitHubData) with an instance of one of the classes extending GitHubData, or you can create your own. Thanks to GSON's magic, this is ridiculously simple, and if you've gotten this far you can probably figure it out yourself just by looking at the source code.

After calling addRequest() with an instance of GitHubData, Attribouter will obtain and parse the data itself (as well as caching, combining duplicate requests, and other complicated things), and will pass it back to the onInit(GitHubData) method - which you should probably extend - of your wedge class, where you can modify any of your wedge's data with the information you have obtained. Once onInit has been called, Attribouter will notify the RecyclerView of a change to your wedge, and you wedge's bind() method will be called shortly afterwards.

As an example, here is a wedge based on the previous examples that initially displays my name in a TextView as "James Fern", then makes a request to GitHub, correcting it to "James Fenn":

public class MyWedge extends Wedge<MyWedge.MyViewHolder> {

 private String myName;
 
 public MyWedge(XmlResourceParser parser) {
   super(R.layout.this_is_a_textview);
   
   myName = "James Fern";
   addRequest(new UserData("TheAndroidMaster"));
   
   addChildren(parser);
 }
 
 @Override
 public MyViewHolder getViewHolder(View v) {
   return new MyViewHolder(v);
 }
 
 @Override
 public void bind(Context context, MyViewHolder viewHolder) {
   viewHolder.textView.setText(myName);
 }
 
 @Override
 public void onInit(GitHubData data) {
   if (data instanceof UserData) {
     UserData user = (UserData) data;
     myName = user.name;
   }
 }
 
 public static class MyViewHolder extends ViewHolder {
 
   TextView textView;
 
   public MyViewHolder(View v) {
     super(v);
     textView = (TextView) v;
   }
 
 }
 
}