Last active
August 29, 2015 13:58
-
-
Save gilliek/9950754 to your computer and use it in GitHub Desktop.
Simple (and not very robust) script that maps the View items of an Android activity layout to an Activity class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
=begin | |
_ ____ _ | |
| | __ _ _ _|___ \ __ _ ___| |_ | |
| |/ _` | | | | __) / _` |/ __| __| | |
| | (_| | |_| |/ __/ (_| | (__| |_ | |
|_|\__,_|\__, |_____\__,_|\___|\__| | |
|___/ | |
lay2act aims to be a very simple (and not very robust) script that maps the View | |
items of an Android activity layout to an Activity class. This script does not | |
fix imports, your IDE has to do it itself. | |
LICENSE | |
"THE BEER-WARE LICENSE" (Revision 42): | |
<[email protected]> wrote this file. As long as you retain | |
this notice you can do whatever you want with this stuff. If we meet some | |
day, and you think this stuff is worth it, you can buy me a beer in return | |
Kevin Gillieron | |
DEPENDENCIES | |
- ruby (it should work with any version of Ruby) | |
- nokogiri (gem install nokogiri) | |
USAGE | |
ruby lay2act ANDROID_LAYOUT ANDROID_ACTIVITY | |
where ANDROID_LAYOUT is the path to the Android layout file and | |
ANDROID_ACTIVITY is the path to the Android Activity class file. | |
=end | |
require 'nokogiri' | |
require 'fileutils' | |
class View | |
attr_reader :type, :id | |
def initialize(type="", id="") | |
@type = type | |
@id = id | |
end | |
end | |
class String | |
def to_camel | |
# http://stackoverflow.com/a/11411200/1061579 | |
self.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join | |
end | |
end | |
def parse_id(id="") | |
id.sub("@+id/", "") | |
end | |
def get_views(xml="") | |
doc = Nokogiri.XML(xml) | |
views = [] | |
doc.traverse do |node| | |
id = node["android:id"] | |
next if id == nil | |
views << View.new(node.name, parse_id(id)) | |
end | |
views | |
end | |
def fmt_attr(view) | |
"\tprivate #{view.type} #{view.id.to_camel};" | |
end | |
def gen_attrs(views) | |
views.inject([]){ |buffer, v| buffer << fmt_attr(v) }.sort.join("\n") | |
end | |
def fmt_assign(view) | |
"\t\tthis.#{view.id.to_camel} = (#{view.type}) this.findViewById(R.id.#{view.id});" | |
end | |
def gen_assign(views) | |
views.inject([]){ |buffer, v| buffer << fmt_assign(v) }.sort.join("\n") | |
end | |
def usage(status=1) | |
puts "usage: #{File.basename($0)} [ANDROID_LAYOUT] [ANDROID_ACTIVITY]" | |
exit status | |
end | |
begin | |
if ARGV.length == 1 && ["-h", "--help"].include?(ARGV[0]) | |
usage(0) | |
# NOTREACHED | |
elsif ARGV.length != 2 | |
STDERR.puts "Invalid # of arguments!" | |
usage | |
# NOTREACHED | |
end | |
layout = ARGV[0] | |
activity = ARGV[1] | |
xml = File.open(layout).readlines.join | |
views = get_views(xml) | |
tmpFilename = activity + ".tmp" | |
output = File.new(tmpFilename, "w") | |
begin | |
re = Regexp.new("(this\\.)setContentView\\(R\\.layout\\.#{File.basename(layout, ".xml")}\\);") | |
File.open(activity).readlines.each do |line| | |
output.puts(line) | |
if line =~ /^public class \w+Activity/i | |
output.puts(gen_attrs(views) + "\n\n") | |
elsif re.match(line) | |
output.puts("\n" + gen_assign(views)) | |
end | |
end | |
ensure | |
output.close | |
end | |
FileUtils.mv(tmpFilename, activity) | |
end | |
# vim: set ts=2 sw=2 noet: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment